Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
13 changes: 13 additions & 0 deletions bootstrap/src/compiler.rs
Original file line number Diff line number Diff line change
Expand Up @@ -17876,7 +17876,20 @@ impl CCodegen {
// unsigned comparison against it inverts (the same
// class the Zig backend fixed as comptime_int).
if w == "u64" { "uint64_t".to_string() } else { "uint32_t".to_string() }
} else if !node.children.is_empty() {
// GNU `__auto_type`: the type follows the INITIALISER,
// which is what Rust's `let` and Zig's `const` do.
// The `int` fallback below caught everything the two
// arms above miss -- a CALL among them -- and silently
// truncated it: `const v = big()` with `big() -> u64`
// made C print 1 where Rust and Zig print 4294967297,
// and the C compiled without a diagnostic.
//
// Same builtin the tuple-destructure paths above
// already emit, so it costs no new portability.
"__auto_type".to_string()
} else {
// No initialiser: `__auto_type` has nothing to follow.
"int".to_string()
};
self.write(&format!("{} {}", c_type, node.name));
Expand Down
2 changes: 1 addition & 1 deletion bootstrap/stage0/FROZEN_HASH
Original file line number Diff line number Diff line change
@@ -1 +1 @@
ff31ebbf36eb1b0ec4a370c8132f27f5d6c79b8d0b2d2c4f8e504b2d42f0f9c2
78bc6d9b03a1ab33729361e558030cd5c67f82d9acdd782912317eaa6d0ea46f
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
# NOW -- C typed an un-annotated local as int and printed 1 for 4294967297 (2026-08-28)

## C typed an un-annotated local as int and printed 1 for 4294967297 (Refs #2161)

- Refs #2161. gen-c fell back to C int for a local with no declared type. Two arms above already special-case integer literals, so the fallback caught everything else -- a CALL among them. `const v = big()` with `big() -> u64` became `int v = big()`: C prints 1 where Rust and Zig print 4294967297, and the C compiles WITHOUT a diagnostic
- Fixed with GNU __auto_type when there is an initialiser -- the same builtin the tuple-destructure paths a few hundred lines above already emit, so no new portability cost. Without an initialiser there is nothing to follow and int stays
- Measured over 746 specs: C output changes for 396, cc -fsyntax-only -std=gnu11 errors 6163 -> 5958, specs with clean C 19 -> 20, and specs that went clean -> broken ZERO. At a radius of 396 that last number is the one that matters, and counting only the sum would have hidden a swap
Loading