diff options
| author | 2026-10-15 22:15:38 +0330 | |
|---|---|---|
| committer | 2026-10-15 22:15:38 +0330 | |
| commit | be43babc1886fc5efee898b2a3d0285012e511fb (patch) | |
| tree | b7ae73e7a6d4c896e2c49b7090168ef589b574af /src/compiler/stmt.zc | |
| parent | merge 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.zc | 16 |
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; } |
