gen-c: put the brackets after the name in a module array constant - #3458
Merged
Conversation
Closes #3457 const A : [4]u8 = [1,2,3,4]; static const [4]u8 A = { 1, 2, 3, 4 }; error: brackets are not allowed here; to declare an array, place the brackets after the identifier The MUTABLE TWIN four lines above the site the probe found carried the same defect -- `var A : [4]u8` gives `static [4]u8 A` -- and only a grep for every site that builds a declarator from a type and a name turned it up. A slice constant was broken before either: `const A : []u8` gave `static const []u8 A`, where `T name[] = { ... }` is legal C and takes its size from the list. Fourth position for one rule, built from the field helper rather than a fourth copy of it: parameter T x[static N] #3435 struct field T f[N]; #3446 local T x[N]; #3448 module const T name[N] here MEASURED, whole corpus, -ferror-limit=0: errors 15126 -> 15021 files that compile 301 -> 302 files better 11 `math/e8_lie_algebra` 44 -> 4, `fpga/mac` 101 -> 85, `queen/lotus` 29 -> 16. ONE FILE'S COUNT ROSE AND IT IS NOT A REGRESSION. `isa/registers` goes 34 -> 44 because the declarations now PARSE: the errors that disappear are `brackets are not allowed here` and two `expected ';'`, and what appears behind them is semantic -- `TernaryWord{.raw=0}` is not C, a separate defect the parse cascade had been hiding. A raw error count is not monotone under a repair that fixes a parse error; the per-file split is what makes that visible. MY OWN TEST ASSERTED SOMETHING THAT NEVER EXISTED. It required a slice const to keep "the old pointer lowering", and there was no pointer lowering -- the type went through verbatim. The test was wrong AND the code was wrong, and the test failing is what showed both. A MUTANT SURVIVED AND THE ANSWER WAS TO DELETE. A `has_init` parameter guarded a case neither caller can produce, so the mutant deleting its check changed nothing. A guard nothing can reach is not protection: the parameter is removed rather than annotated. Two other mutants died. Round six of the parity table, the const-initialiser position it had never covered. The previous round found only latent defects; this one found a live one on its first form, so the table does not stop yet. 28 seals refreshed in the same commit. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
gHashTag
enabled auto-merge (squash)
September 8, 2026 03:21
Contributor
|
📓 NotebookLM Notebook linked to this PR
This notebook contains session context, decisions, and artifacts for this work. |
Contributor
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Closes #3457
The mutable twin four lines above the site the probe found had the same
defect (
var A : [4]u8→static [4]u8 A), and only a grep for everydeclarator-building site turned it up. A slice constant was broken before
either:
static const []u8 A, whereT name[] = { … }is legal C.Fourth position for one rule
T x[static N]T f[N];T x[N];T name[N]Built from the field helper, not a fourth copy.
Measured — whole corpus,
-ferror-limit=0math/e8_lie_algebra44 → 4 ·fpga/mac101 → 85 ·queen/lotus29 → 16 ·boards/xc7a100t_minimal11 → 1.One file's count rose and it is not a regression.
isa/registersgoes34 → 44 because the declarations now parse: what disappears is
brackets are not allowed hereand twoexpected ';'; what appears behind them is semantic(
TernaryWord{.raw=0}is not C — a separate defect the cascade was hiding). Araw error count is not monotone under a repair that fixes a parse error.
Two things I got wrong, both caught here
My own test asserted something that never existed — that a slice const must
keep "the old pointer lowering". There was no pointer lowering; the type went
through verbatim. The test was wrong and the code was wrong, and the failing
test showed both.
A mutant survived and the answer was to delete. A
has_initparameterguarded a case neither caller can produce. A guard nothing can reach is not
protection, so it is removed rather than annotated.
has_initcheck removedFull suite: 2630 passed, 0 failed. 28 seals refreshed in the same commit.
The round
Round six of
tools/backend_parity_table.py— the const-initialiser positionit had never covered. Round five found only latent defects; this one found a
live one on its first form, so the table does not stop yet.