aboutsummaryrefslogtreecommitdiff
path: root/src/compiler/decl.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/decl.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/decl.zc')
-rw-r--r--src/compiler/decl.zc18
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];