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/decl.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/decl.zc')
| -rw-r--r-- | src/compiler/decl.zc | 18 |
1 files changed, 9 insertions, 9 deletions
diff --git a/src/compiler/decl.zc b/src/compiler/decl.zc index 313d1ab..b6669b1 100644 --- a/src/compiler/decl.zc +++ b/src/compiler/decl.zc @@ -94,7 +94,7 @@ int prescan_maker() { // the guess only makes the function compile as if declared .u; its body is then // checked against that, so a wrong guess is an error, never a silent leak. int prescan_owned(int self) { - int depth = 0, n, k, found = 0, nown = 0, decl = 0; let owned[16]; + int depth = 0, n, k, found = 0, nown = 0, decl = 0; let owned[16] = {}; while (tk != T_EOF) { // a declaration's name follows a type name, a *, let or a comma; a plain // assignment (to a global, say) follows ; { or } @@ -385,7 +385,7 @@ int borrows_check(int s, int np, char** pn, word pty) { return 0; } int fndef(int chk, int rty, int ret, int n) { - int s, np = 0, tags = 0, t, sig, i; char*[24] pn; word[24] pt; word[24] pty; int typed = 0, ft, explicit_rty = !!rty, o3f = o3nxt, lo, hi, pk, lt, lend, lfl = tline, redef, amb = 0, nonm = 0; + int s, np = 0, tags = 0, t, sig, i; char*[24] pn = {}; word[24] pt = {}; word[24] pty = {}; int typed = 0, ft, explicit_rty = !!rty, o3f = o3nxt, lo, hi, pk, lt, lend, lfl = tline, redef, amb = 0, nonm = 0; o3nxt = 0; if (rty || ntp) typed = 1; if (!dnm) dnm = n; @@ -500,7 +500,7 @@ int fndef(int chk, int rty, int ret, int n) { prologue(); borrow_prologue(); hold_gate(57); i = 0; while (i < np) { - t = newloc(pn[i]); lrskind[t] = RS_PARAM; lrsoff[t] = pnoffs[i]; lpos[t] = pnplaces[i]; fslots++; lsmark(1, pn[i]); + t = newloc(pn[i]); lrskind[t] = RS_PARAM; lrsoff[t] = pnoffs[i]; lpos[t] = pnplaces[i]; fslots++; lsmark(1, pn[i]); mark_inited(t); ltype[t] = pty[i]; lptr[t] = 0; if (ifcur && if_local && i < IFP) if_local[t] = ifcur + 8 + 3 * i; lt_note(pnoffs[i], pty[i]); @@ -645,7 +645,7 @@ int gconst() { // lays out the descriptor the install opcode reads, and wires it in right // away (an image wires its own in when it boots). int enhdef() { - int n, np = 0, nout = 1, dsc, na, pay, len = 0, kind = 0, i; word p; int s, slot, r; char*[8] pn; + int n, np = 0, nout = 1, dsc, na, pay = 0, len = 0, kind = 0, i; word p; int s, slot, r; char*[8] pn = {}; next(); // enhance 2 divmod(a, b) if (tk == T_NUM) { @@ -711,7 +711,7 @@ int topsync() { // after a function's name: <T, U> declares its type parameters. any the return // type used were taken on trust; now they get their real numbers int genparams() { - int i, j, n = 0; char*[8] ps; word[8] bs; + int i, j, n = 0; char*[8] ps = {}; word[8] bs = {}; if (!is_op(s_lt)) { if (ntp) serrn(tpn[0], "isn't a type"); ntp = 0; return 0; } next(); while (1) { @@ -1012,7 +1012,7 @@ int fn_remember(int s, int name) { // their original globals and entry addresses. int syntax_host_function(int symbol) { word meta = fnmeta[symbol], source, full; int clone, count, name; - char[40] generated; char[24] reversed; int sequence = fnpatchseq, digits = 0, i = 0; + char[40] generated = {}; char[24] reversed = {}; int sequence = fnpatchseq, digits = 0, i = 0; if (syntax_host_symbols[symbol]) return syntax_host_symbols[symbol] - 1; if (!meta || (sflag[symbol] & F_GEN)) { serr("an emitted syntax dependency requires retained nongeneric source"); return -1; } fnpatchseq++; @@ -1049,7 +1049,7 @@ int syntax_resident(int symbol) { // queued to be compiled once the template's tokens are in. a type parameter // that nothing bound is a plain word. word ginstance(int s, word bs) { - int k = 0, t = 0 - 1, np, i, j, ns; char* nm; char[24] dg; int nd; char* a; + int k = 0, t = 0 - 1, np, i, j, ns; char* nm; char[24] dg = {}; int nd; char* a; if (dry || !gtab) return s; while (k < gt_n) { if (gt_sym[k] == s) { t = k; break; } @@ -1159,7 +1159,7 @@ int unit_top() { } // the edit distance between two names (levenshtein), or 99 when one is too long word editdist(word a, word b) { - int la = rt.len_w(a), lb = rt.len_w(b), i, j, x, y, z, last, row[65]; + int la = rt.len_w(a), lb = rt.len_w(b), i, j, x, y, z, last, row[65] = {}; if (la > 60 || lb > 60) return 99; j = 0; while (j <= lb) { row[j] = j; j++; } i = 1; @@ -1519,7 +1519,7 @@ word*.u function_tokens(int addr) { int replace_function(int addr, word* body_tokens) { int s = 0, open, close, namepos, olderr = nerr, oldpanic = panic, oldabort = chkabort; int errors, generated_id, new_symbol, count, i = 0, out = 0, cap, diag, seq, digits = 0, published; - char[40] generated; char[24] reversed; word meta, source, full, imports; char* module; + char[40] generated = {}; char[24] reversed = {}; word meta, source, full, imports; char* module; while (s < nsym && !(skind[s] == K_FN && sval[s] == addr && fnmeta[s])) s++; if (s >= nsym || !body_tokens || body_tokens[0] < 0) return 0; meta = fnmeta[s]; source = meta[0]; open = meta[4]; close = meta[5]; namepos = meta[3]; module = meta[1]; imports = meta[2]; |
