fix(0138): diagnose @scalar-const address-of (no storage)
A scalar `::` constant folds to its value and has no storage. The unary `.address_of` lowering (src/ir/lower/expr.zig) skipped the alloca path (is_alloca == false) and resolveGlobalRef (scalar consts get no storage global), falling through to the generic addr_of arm, which reinterpreted the folded value as a pointer: `inttoptr (i64 <value> to ptr)`. That wild pointer segfaulted on deref and emitted invalid stores for inline-asm `-> @const`. Diagnose instead, in the address_of(identifier) path: a non-alloca, non-ref-capture, non-pack-elem scope binding (local scalar const) and a module_const_map name not backed by storage (module scalar const) both report "cannot take the address of constant '<name>' — a scalar '::' constant has no storage …" and return a placeholder Ref. Chose diagnose over materializing read-only storage (consistent with the fold-only scalar model). Array/struct consts keep real storage and stay addressable (@K/@LIT unchanged). Also gives the ASM stream's planned output-to-const rejection for free — asm `-> @const` lowers through the same path. Regression: examples/1177-diagnostics-addr-of-const-rejected.sx. Resolves 0138.
This commit is contained in:
18
examples/1177-diagnostics-addr-of-const-rejected.sx
Normal file
18
examples/1177-diagnostics-addr-of-const-rejected.sx
Normal file
@@ -0,0 +1,18 @@
|
||||
// Taking the address of a scalar `::` constant is a compile error: a scalar
|
||||
// constant folds to its value and has NO storage (only array/struct constants
|
||||
// are immutable globals with a real address — see 0177). Covers a module-scope
|
||||
// const, a local const, and an inline-asm `-> @const` write-through (the path
|
||||
// that surfaced the bug). Before the fix, `@N` lowered to `inttoptr (i64 40 to
|
||||
// ptr)` — a wild pointer that segfaulted on deref and emitted invalid stores
|
||||
// for asm `-> @const`. Regression (issue 0138).
|
||||
|
||||
takes :: (p: *i64) {}
|
||||
|
||||
N :: 40;
|
||||
|
||||
main :: () {
|
||||
takes(@N); // module scalar const — no storage
|
||||
x :: 7;
|
||||
takes(@x); // local scalar const — no storage
|
||||
asm volatile { "mov %[c], #99", [c] "=r" -> @N }; // write-through to a const
|
||||
}
|
||||
@@ -0,0 +1 @@
|
||||
1
|
||||
@@ -0,0 +1,17 @@
|
||||
error: cannot take the address of constant 'N' — a scalar '::' constant has no storage (use a '=' variable or a local copy for mutable data)
|
||||
--> examples/1177-diagnostics-addr-of-const-rejected.sx:14:11
|
||||
|
|
||||
14 | takes(@N); // module scalar const — no storage
|
||||
| ^^
|
||||
|
||||
error: cannot take the address of constant 'x' — a scalar '::' constant has no storage (use a '=' variable or a local copy for mutable data)
|
||||
--> examples/1177-diagnostics-addr-of-const-rejected.sx:16:11
|
||||
|
|
||||
16 | takes(@x); // local scalar const — no storage
|
||||
| ^^
|
||||
|
||||
error: cannot take the address of constant 'N' — a scalar '::' constant has no storage (use a '=' variable or a local copy for mutable data)
|
||||
--> examples/1177-diagnostics-addr-of-const-rejected.sx:17:49
|
||||
|
|
||||
17 | asm volatile { "mov %[c], #99", [c] "=r" -> @N }; // write-through to a const
|
||||
| ^^
|
||||
@@ -0,0 +1 @@
|
||||
|
||||
Reference in New Issue
Block a user