gen-c: a negative element makes a literal list signed - #3463
Merged
Conversation
Refs #3459 670 `__auto_type x = { ... }` errors remained and had never been categorised. Printing them BY SHAPE before writing any code split the wall into six families: 319 { 0 } an EMPTY list ~92 { cast_iN(N), ... } calls ~85 { N, -N, ... } a negative element 32 { N.NeN } an exponent suffix 21 { Trit.pos, ... } enum member access 12 { "s", "s" } strings THE LARGEST FAMILY CANNOT BE INFERRED AT ALL, and finding that out is why the measurement came first. `{ 0 }` comes from `var x = []`, of which the specs contain 439. C11 has no `{}`, so `{ 0 }` is the emitter's stand-in, and an empty list has nothing to take a type from. Naming one would be inventing it, and a test now pins that it keeps `__auto_type`. The tractable family was the negatives, 193 corpus sites. A negative element is a UNARY EXPRESSION, not a literal, so the whole list was refused. Looking through the `-` was the easy half; the first version then emitted uint32_t x[2] = { 1, -1 }; an unsigned type holding a negative -- exactly the quiet wrong answer this class of repairs exists to avoid. A negative now makes the list `i32`. MEASURED, whole corpus, -ferror-limit=0: errors 14165 -> 14041 __auto_type with initializer list 670 -> 523 files better 11 Two files worse, both unmasking. Sign diagnostics unchanged -- 7 `-Wsign-compare` and 60 conversions on both sides -- so the signed choice introduced none. Across three passes the class has gone 1729 -> 523. ONLY `-` IS LOOKED THROUGH. `[!1]` keeps `__auto_type`: a unary whose value is not the literal underneath it would have the list typed from the wrong number. A mutant widening this to any unary operator dies on that test. A mutant forcing the children branch to "u32" SURVIVES, and it is written into the comment rather than papered over: an integer list carrying a negative takes the `extra_size` path -- probed with `[1, -1]`, `[-1]` and `[_]i32{1, -1}` -- and the float case that does reach the children branch is answered by `any_float` before the sign matters. The branch is reachable; that combination has not been produced. 19 seals refreshed in the same commit. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
gHashTag
enabled auto-merge (squash)
September 8, 2026 04:59
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.
Refs #3459
670
__auto_type x = { … }errors remained and had never beencategorised. Printing them by shape before writing any code split the wall
into six families:
{ 0 }{ cast_iN(N), … }{ N, -N, … }{ N.NeN }{ Trit.pos, … }{ "s", "s" }The largest family cannot be inferred at all
{ 0 }comes fromvar x = []— 439 such sites in the specs. C11 has no{}, so{ 0 }is the emitter's stand-in, and an empty list has nothing totake a type from. Naming one would be inventing it; a test now pins that it
keeps
__auto_type.Finding this out is why the measurement came first.
The tractable family: negatives
A negative element is a unary expression, not a literal, so the whole list
was refused — 193 corpus sites. Looking through the
-was the easy half. Thefirst version then emitted:
an unsigned type holding a negative — exactly the quiet wrong answer this
class of repairs exists to avoid. A negative now makes the list
i32.Measured —
-ferror-limit=0__auto_typewith initializer listTwo worse, both unmasking. Sign diagnostics unchanged — 7
-Wsign-compareand 60 conversions on both sides — so the signed choice introduced none.
Across three passes: 1729 → 523.
Only
-is looked through[!1]keeps__auto_type: a unary whose value is not the literal underneathwould type the list from the wrong number.
u32The survivor is recorded rather than papered over: an integer list carrying a
negative takes the
extra_sizepath — probed with[1, -1],[-1]and[_]i32{1, -1}— and the float case that does reach the children branch isanswered by
any_floatbefore the sign matters.Full suite: 2645 passed, 0 failed. 19 seals refreshed in the same commit.