Skip to content

gen-c: a fixed-size [N]T parameter loses its size and the caller is never checked #3434

Description

@gHashTag

What

gen-c lowers a fixed-size array parameter to a bare pointer:

fn fixed(a: [4]u8) -> u8 { return a[0]; }
uint8_t fixed(uint8_t* a);

The length is gone. A caller passing a two-element array compiles silently.

The other two backends keep it: gen-rust emits [u8; 4], gen-verilog/Zig
keep [4]u8. C is the one column that drops it -- the same cross-backend
divergence pattern as #3403 and #3423.

Measured, not assumed

The obvious spelling does not fix it. Apple clang 21, -Wall -Wextra,
passing a 2-element array where 4 are required:

prototype diagnostic
void f(uint64_t a[4]); (silence)
void f(uint64_t a[static 4]); warning: array argument is too small; contains 2 elements, callee requires at least 4 [-Warray-bounds]

A plain [N] parameter decays to a pointer and checks nothing. Only
[static N] carries the contract.

Population

Counted by the emitter itself, over all 651 specs (583 of which emit C):

  • 51 parameters in 24 functions across 12 files.

Concentrated in specs/ternary/bitnet_* (28), specs/vsa/ops (9) and
specs/compiler/lexer (3).

Scope

This is a guard for future and out-of-repo callers -- compiling the generated
corpus today produces 0 -Warray-bounds, so it finds no existing defect.
Its value is that the next short call is rejected instead of accepted.

Constraints found while scoping

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