aboutsummaryrefslogtreecommitdiff
path: root/tests
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 /tests
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 'tests')
-rw-r--r--tests/conformance/4-statements/uninit_array_init_ok.zc10
-rw-r--r--tests/conformance/4-statements/uninit_assigned_ok.zc11
-rw-r--r--tests/conformance/4-statements/uninit_both_branches_ok.zc11
-rw-r--r--tests/conformance/4-statements/uninit_branch_rejected.zc10
-rw-r--r--tests/conformance/4-statements/uninit_do_loop_ok.zc12
-rw-r--r--tests/conformance/4-statements/uninit_loop_rejected.zc11
-rw-r--r--tests/conformance/4-statements/uninit_outparam_agg_ok.zc13
-rw-r--r--tests/conformance/4-statements/uninit_outparam_ok.zc12
-rw-r--r--tests/conformance/4-statements/uninit_partial_struct_rejected.zc11
-rw-r--r--tests/conformance/4-statements/uninit_read_rejected.zc5
-rw-r--r--tests/conformance/4-statements/uninit_struct_init_ok.zc11
-rw-r--r--tests/errors/uninit_branch.zc10
-rw-r--r--tests/errors/uninit_loop.zc11
-rw-r--r--tests/errors/uninit_partial_array.zc10
-rw-r--r--tests/errors/uninit_partial_struct.zc12
-rw-r--r--tests/errors/uninit_read.zc9
16 files changed, 169 insertions, 0 deletions
diff --git a/tests/conformance/4-statements/uninit_array_init_ok.zc b/tests/conformance/4-statements/uninit_array_init_ok.zc
new file mode 100644
index 0000000..d291448
--- /dev/null
+++ b/tests/conformance/4-statements/uninit_array_init_ok.zc
@@ -0,0 +1,10 @@
+// expect: 10/
+// spec 4.1.5: a full array initializer list initializes the array
+include rt;
+void pn(int x) { rt.put_n(x); rt.put_c(10); }
+fn main() {
+ int[4] a = { 1, 2, 3, 4 };
+ pn(a[0] + a[1] + a[2] + a[3]);
+ return 0;
+}
+// zc0: skip
diff --git a/tests/conformance/4-statements/uninit_assigned_ok.zc b/tests/conformance/4-statements/uninit_assigned_ok.zc
new file mode 100644
index 0000000..6c831a4
--- /dev/null
+++ b/tests/conformance/4-statements/uninit_assigned_ok.zc
@@ -0,0 +1,11 @@
+// expect: 3/
+// spec 4.1.5: a local assigned before use is fine
+include rt;
+void pn(int x) { rt.put_n(x); rt.put_c(10); }
+fn main() {
+ int x;
+ x = 3;
+ pn(x);
+ return 0;
+}
+// zc0: skip
diff --git a/tests/conformance/4-statements/uninit_both_branches_ok.zc b/tests/conformance/4-statements/uninit_both_branches_ok.zc
new file mode 100644
index 0000000..205acdf
--- /dev/null
+++ b/tests/conformance/4-statements/uninit_both_branches_ok.zc
@@ -0,0 +1,11 @@
+// expect: 1/
+// spec 4.1.5: every branch assigns before the join
+include rt;
+void pn(int x) { rt.put_n(x); rt.put_c(10); }
+fn main() {
+ int x;
+ if (1) x = 1; else x = 2;
+ pn(x);
+ return 0;
+}
+// zc0: skip
diff --git a/tests/conformance/4-statements/uninit_branch_rejected.zc b/tests/conformance/4-statements/uninit_branch_rejected.zc
new file mode 100644
index 0000000..ca93c39
--- /dev/null
+++ b/tests/conformance/4-statements/uninit_branch_rejected.zc
@@ -0,0 +1,10 @@
+// expect error: used before it is initialized
+// spec 4.1.5: a local set on only some branches is unset at the join
+include rt;
+fn main() {
+ int x;
+ if (0) x = 1;
+ rt.put_n(x);
+ return 0;
+}
+// zc0: skip
diff --git a/tests/conformance/4-statements/uninit_do_loop_ok.zc b/tests/conformance/4-statements/uninit_do_loop_ok.zc
new file mode 100644
index 0000000..4f09302
--- /dev/null
+++ b/tests/conformance/4-statements/uninit_do_loop_ok.zc
@@ -0,0 +1,12 @@
+// expect: 1/
+// spec 4.1.5: do/while always runs once, so an assignment in the body initializes
+include rt;
+void pn(int x) { rt.put_n(x); rt.put_c(10); }
+fn main() {
+ int x;
+ int n = 0;
+ do { x = 1; n = 0; } while (n);
+ pn(x);
+ return 0;
+}
+// zc0: skip
diff --git a/tests/conformance/4-statements/uninit_loop_rejected.zc b/tests/conformance/4-statements/uninit_loop_rejected.zc
new file mode 100644
index 0000000..67d8120
--- /dev/null
+++ b/tests/conformance/4-statements/uninit_loop_rejected.zc
@@ -0,0 +1,11 @@
+// expect error: used before it is initialized
+// spec 4.1.5: a loop that may run zero times does not initialize
+include rt;
+fn main() {
+ int x;
+ int n = 0;
+ while (n) x = 1;
+ rt.put_n(x);
+ return 0;
+}
+// zc0: skip
diff --git a/tests/conformance/4-statements/uninit_outparam_agg_ok.zc b/tests/conformance/4-statements/uninit_outparam_agg_ok.zc
new file mode 100644
index 0000000..75ba07d
--- /dev/null
+++ b/tests/conformance/4-statements/uninit_outparam_agg_ok.zc
@@ -0,0 +1,13 @@
+// expect: 5/
+// spec 4.1.5: &aggregate counts as initializing the whole aggregate
+include rt;
+struct point { int x; int y; }
+void pn(int x) { rt.put_n(x); rt.put_c(10); }
+void fill(point* p) { p->x = 2; p->y = 3; }
+fn main() {
+ point p;
+ fill(&p);
+ pn(p.x + p.y);
+ return 0;
+}
+// zc0: skip
diff --git a/tests/conformance/4-statements/uninit_outparam_ok.zc b/tests/conformance/4-statements/uninit_outparam_ok.zc
new file mode 100644
index 0000000..e97f54b
--- /dev/null
+++ b/tests/conformance/4-statements/uninit_outparam_ok.zc
@@ -0,0 +1,12 @@
+// expect: 7/
+// spec 4.1.5: passing &x counts as initializing x
+include rt;
+void pn(int x) { rt.put_n(x); rt.put_c(10); }
+void fill(int* p) { *p = 7; }
+fn main() {
+ int x;
+ fill(&x);
+ pn(x);
+ return 0;
+}
+// zc0: skip
diff --git a/tests/conformance/4-statements/uninit_partial_struct_rejected.zc b/tests/conformance/4-statements/uninit_partial_struct_rejected.zc
new file mode 100644
index 0000000..9c71f92
--- /dev/null
+++ b/tests/conformance/4-statements/uninit_partial_struct_rejected.zc
@@ -0,0 +1,11 @@
+// expect error: used before it is initialized
+// spec 4.1.5: writing some fields does not initialize the aggregate
+include rt;
+struct point { int x; int y; }
+fn main() {
+ point p;
+ p.x = 1;
+ rt.put_n(p.y);
+ return 0;
+}
+// zc0: skip
diff --git a/tests/conformance/4-statements/uninit_read_rejected.zc b/tests/conformance/4-statements/uninit_read_rejected.zc
new file mode 100644
index 0000000..3ef407a
--- /dev/null
+++ b/tests/conformance/4-statements/uninit_read_rejected.zc
@@ -0,0 +1,5 @@
+// expect error: used before it is initialized
+// spec 4.1.5: reading a local before any assignment is an error
+include rt;
+fn main() { int x; rt.put_n(x); return 0; }
+// zc0: skip
diff --git a/tests/conformance/4-statements/uninit_struct_init_ok.zc b/tests/conformance/4-statements/uninit_struct_init_ok.zc
new file mode 100644
index 0000000..ab033ae
--- /dev/null
+++ b/tests/conformance/4-statements/uninit_struct_init_ok.zc
@@ -0,0 +1,11 @@
+// expect: 9/
+// spec 4.1.5: while(1) always enters, so an assignment before break initializes
+include rt;
+void pn(int x) { rt.put_n(x); rt.put_c(10); }
+fn main() {
+ int x;
+ while (1) { x = 9; break; }
+ pn(x);
+ return 0;
+}
+// zc0: skip
diff --git a/tests/errors/uninit_branch.zc b/tests/errors/uninit_branch.zc
new file mode 100644
index 0000000..e4d253b
--- /dev/null
+++ b/tests/errors/uninit_branch.zc
@@ -0,0 +1,10 @@
+namespace;
+include rt;
+
+// expect: x: used before it is initialized
+fn main() {
+ int x;
+ if (rt.get_c()) x = 1;
+ rt.put_n(x);
+ return 0;
+}
diff --git a/tests/errors/uninit_loop.zc b/tests/errors/uninit_loop.zc
new file mode 100644
index 0000000..d345296
--- /dev/null
+++ b/tests/errors/uninit_loop.zc
@@ -0,0 +1,11 @@
+namespace;
+include rt;
+
+// expect: x: used before it is initialized
+fn main() {
+ int x;
+ int n = 0;
+ while (n) { x = 1; n = 0; }
+ rt.put_n(x);
+ return 0;
+}
diff --git a/tests/errors/uninit_partial_array.zc b/tests/errors/uninit_partial_array.zc
new file mode 100644
index 0000000..d30310f
--- /dev/null
+++ b/tests/errors/uninit_partial_array.zc
@@ -0,0 +1,10 @@
+namespace;
+include rt;
+
+// expect: a: used before it is initialized
+fn main() {
+ int[4] a;
+ a[0] = 1;
+ rt.put_n(a[1]);
+ return 0;
+}
diff --git a/tests/errors/uninit_partial_struct.zc b/tests/errors/uninit_partial_struct.zc
new file mode 100644
index 0000000..7b65481
--- /dev/null
+++ b/tests/errors/uninit_partial_struct.zc
@@ -0,0 +1,12 @@
+namespace;
+include rt;
+
+struct point { int x; int y; }
+
+// expect: p: used before it is initialized
+fn main() {
+ point p;
+ p.x = 1;
+ rt.put_n(p.y);
+ return 0;
+}
diff --git a/tests/errors/uninit_read.zc b/tests/errors/uninit_read.zc
new file mode 100644
index 0000000..3a18a95
--- /dev/null
+++ b/tests/errors/uninit_read.zc
@@ -0,0 +1,9 @@
+namespace;
+include rt;
+
+// expect: x: used before it is initialized
+fn main() {
+ int x;
+ rt.put_n(x);
+ return 0;
+}