Skip to content

gen-c: the element type of a LOCAL array is passed through unmapped (W583, second position) #3448

Description

@gHashTag

What

fn probe(v: i32) -> i32 { var x : [4]GF16; return 0; }
GF16 x[4];
error: use of undeclared identifier 'GF16'

The same element is lowered correctly everywhere else:

position emitted
parameter uint16_t a[static 4]
struct field uint16_t f[4];
local GF16 x[4];

This is W583, in a position the repair never reached

The local path gates on is_primitive:

let c_elem = if Self::is_primitive(elem) {
    Self::type_to_c(elem).to_string()
} else {
    elem.to_string()          // t27 text, verbatim
};

Two hundred lines below, on param_type_to_c, sits the note retiring exactly that gate:

W583: this used to be gated on is_primitive, which lists only the integer scalars -- so f32, f64, str, string and gf16 took the pass-through arm and reached C unmapped even after type_to_c learned them. type_to_c already passes genuinely custom types through, so the gate only ever suppressed correct mappings.

Same sentence, same file, other position.

Two more in the same eight lines

  • var x : []u8; emits uint8_t x[];"definition of variable with array type needs an explicit size or an initializer". Only without an initialiser: T x[] = {…} is legal C and takes its size from the list.
  • var x : []const u8; emits const u8* x"unknown type name 'u8'". The qualifier lives inside the element text, so the element is the literal const u8; param_type_to_c strips it and this path did not.

Measured

Whole corpus, -ferror-limit=0:

before after
errors 15133 15126
files that compile 301 301
files worse 0

Three files improve: math/property_test_template 46→43, nn/hslm 79→76, numeric/gf16 151→150.

A note on every error count I have published this session

Clang's default -ferror-limit=20 was censoring the aggregate. The corpus emits 15133 errors, not the 3849 I have been reporting — the default stops at twenty per file and 141 files reach it.

The per-file splits I reported were sound (they were counted per file), but the totals were floors. Re-measured without the limit, #3447 moved 15188 → 15133 (−55), not the −24 I published.

Found by

tools/backend_parity_table.py extended to a fourth position, local. The first probe there — var x : T; with no initialiser — measured the wrong thing: Zig and Verilog emit nothing for an uninitialised local, so the table was reading their dead-code removal. Initialising from a parameter of the same type fixed it, and the self-check now covers all four positions.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions