aboutsummaryrefslogtreecommitdiff
path: root/src/compiler/stmt.zc
diff options
context:
space:
mode:
authorGravatar zinc <zinc@downsta.ir> 2026-10-15 22:15:38 +0330
committerGravatar zinc <zinc@downsta.ir> 2026-10-15 22:15:38 +0330
commitbe43babc1886fc5efee898b2a3d0285012e511fb (patch)
treeb7ae73e7a6d4c896e2c49b7090168ef589b574af /src/compiler/stmt.zc
parentmerge work/known-bugs: constant-expression precedence, local const in constan... (diff)
definite assignment: reading a local before it is initialized is a compile error (spec 4.1.5, b.1.9)
track linited per local alongside the ownership state; snapshots, exit records and joins carry it, and a join keeps a local set only when every reaching path set it. x = e, a declaration initializer, &x (out-parameter), a full array initializer, or using an aggregate as an address set a local; field and element writes do not set the aggregate. while/for bodies that may run zero times do not count; do/while does. compiler, runtime, std, actor and lsp sources initialize the locals the rule flagged; zc0 accepts = {} brace lists (zeroed). tests: tests/errors/uninit_*.zc, tests/conformance/4-statements/uninit_*.zc
Diffstat (limited to 'src/compiler/stmt.zc')
-rw-r--r--src/compiler/stmt.zc16
1 files changed, 8 insertions, 8 deletions
diff --git a/src/compiler/stmt.zc b/src/compiler/stmt.zc
index 79e5fb8..2e0cfe3 100644
--- a/src/compiler/stmt.zc
+++ b/src/compiler/stmt.zc
@@ -138,7 +138,7 @@ int localdecl(int typed) {
if (larr[i] && ltype[i][0] == TY_ARR && (is_op(s_lb) || tk == T_STR || tk == T_BSTR)) {
iq = array_initializer_tokens(ltype[i]); it = array_measure(iq, ltype[i]);
fslots = fslots + tsz(it) - tsz(ltype[i]);
- ltype[i] = it; array_initialize(iq, it, lslot[i], 1); rt.free(iq);
+ ltype[i] = it; array_initialize(iq, it, lslot[i], 1); rt.free(iq); mark_inited(i);
} else {
if (larr[i]) serr("an array or a struct needs an initializer list");
newsz = -1; newleaf = 0; if (tk == T_NUM) nomagic = 1;
@@ -159,7 +159,7 @@ int localdecl(int typed) {
else if (xty[0] == TY_STRUCT) ltype[i] = tptr(xty);
else ltype[i] = xty;
}
- assigncheck(LV_LOCAL, i, c);
+ assigncheck(LV_LOCAL, i, c); mark_inited(i);
if (ro) { k = ltype[i]; if (!k) { k = tword; if (isnum(xty)) k = xty; } ltype[i] = tconst(k); }
if (gok) { k = xty; if (isagg(k)) k = ltype[i]; if (!ifpure(k) || (gty && gty != k)) gok = 0; else gty = k; }
}
@@ -271,7 +271,7 @@ int loop_end(int a, int sc) {
njps = 0;
if (sc >= 0) jadd(R_SNAP + sc);
p = R_EXIT + f[6]; e = R_EXIT + extop;
- while (p < e) { jadd(p + 1); p = p + 3 + 3 * (p[2] - p[1]); }
+ while (p < e) { jadd(p + 1); p = p + 3 + 4 * (p[2] - p[1]); }
join(n0, "leaves the loop in different states on different paths");
live = njps > 0;
p = R_EXIT + f[6];
@@ -283,7 +283,7 @@ int loop_end(int a, int sc) {
op(O_JMP);
}
else outs = fixnew(p[0], outs);
- p = p + 3 + 3 * (p[2] - p[1]);
+ p = p + 3 + 4 * (p[2] - p[1]);
}
if (a >= 0) setlit(a, here);
if (sc >= 0) fixups(R_SNAP + sc, n0, 1);
@@ -578,14 +578,14 @@ int case_seen(word seen, int n, int v) {
int kw_switch() {
int sl = tline;
int save = nloc, tmp, c, s0, live0, defent = -1, skip, nxt, bj, v, a = -1, st, tg = 0, cov = 0, gi, nb = 0, j, arm, bi;
- word[8] pbn; word[8] pbl; word[256] seen; int nseen = 0;
+ word[8] pbn = {}; word[8] pbl = {}; word[256] seen = {}; int nseen = 0;
stmtonly();
next();
expect(s_lp); c = expr(); st = xty; rval(); plainuse(c); expect(s_rp);
tg = ptagged(st);
fdepth++;
tmp = newloc(0); fslots++; // a hidden local holds the value
- laddr(lslot[tmp]); op(O_ST);
+ laddr(lslot[tmp]); op(O_ST); mark_inited(tmp);
live0 = live;
s0 = snap_push();
loop_push(-1, s0);
@@ -634,7 +634,7 @@ int kw_switch() {
for (j = 0; j < nb && j < pm_nf[gi]; j++) {
capture_cell(pbl[j], 0);
laddr(lslot[tmp]); op(O_LD); lit(pm_off[gi * 8 + j]); op(O_ADD); op(O_LD);
- vaddr(pbl[j]); op(O_ST);
+ vaddr(pbl[j]); op(O_ST); mark_inited(pbl[j]);
}
casebody(s0, live0);
block_close(arm);
@@ -848,7 +848,7 @@ int asmblock() {
if (tk != T_ID) die("bad token in asm");
i = findloc(tv);
if (i >= 0 && (ltag[i] & 16) && !larr[i]) serr("asm can't reach an o3 variable");
- if (i >= 0) { luse(i); ltag[i] = ltag[i] | LREAD | LASG; vaddr(i); next(); continue; }
+ if (i >= 0) { need_inited(i); luse(i); ltag[i] = ltag[i] | LREAD | LASG; mark_inited(i); vaddr(i); next(); continue; }
if (nclo) {
k = clocap(tv);
if (k >= 0) { vaddr(clo_env[nclo - 1]); op(O_LD); lit(k); op(O_ADD); op(O_LD); next(); continue; }