aboutsummaryrefslogtreecommitdiff
path: root/tests/programs/bounds_hoist.zc
diff options
context:
space:
mode:
authorGravatar zinc <zinc@downsta.ir> 2026-10-14 18:22:04 +0330
committerGravatar zinc <zinc@downsta.ir> 2026-10-14 20:03:38 +0330
commit459b7661aaa0d65d01be064bd4b9976c4f045a5c (patch)
treeeccb0738631fc52e5116fb238c2f7f961784ff36 /tests/programs/bounds_hoist.zc
parentzy: nonzero exit on compile errors (diff)
bounds: body scan, loop-entry hoisting, pointer proofs from requested size, --explain-checks v1 (non-o3 code)
Diffstat (limited to 'tests/programs/bounds_hoist.zc')
-rw-r--r--tests/programs/bounds_hoist.zc20
1 files changed, 20 insertions, 0 deletions
diff --git a/tests/programs/bounds_hoist.zc b/tests/programs/bounds_hoist.zc
new file mode 100644
index 0000000..d7f5e7f
--- /dev/null
+++ b/tests/programs/bounds_hoist.zc
@@ -0,0 +1,20 @@
+namespace;
+include rt;
+
+// a loop for (i = 0; i < n; i++) with an int bound n the body leaves alone:
+// the check of t[i] against t's length is worked out once at the loop entry
+// (0 <= i and n <= length) and runs on each access only when that failed. so
+// a loop that stays inside skips it, and one that runs past the end still
+// faults at the same access, after the same side effects (the puts before it).
+int[8] t;
+int sweep(int n) { int i, s = 0; for (i = 0; i < n; i++) { t[i] = i; s = s + t[i]; } return s; }
+int from(int lo, int n) { int i, s = 0; for (i = lo; i < n; i++) s = s + t[i]; return s; }
+int main() {
+ rt.put_n(sweep(8)); rt.put_c(10);
+ rt.put_n(sweep(3)); rt.put_c(10);
+ rt.put_n(from(2, 8)); rt.put_c(10);
+ int i, n = 10;
+ for (i = 0; i < n; i++) { rt.put_n(i); rt.put_c(32); t[i] = i; }
+ rt.put_s("not reached\n");
+ return 0;
+}