aboutsummaryrefslogtreecommitdiff
path: root/src/compiler/analyzer.zc
diff options
context:
space:
mode:
authorGravatar zinc <zinc@downsta.ir> 2026-10-14 16:25:05 +0330
committerGravatar zinc <zinc@downsta.ir> 2026-10-14 16:25:05 +0330
commit8a7092df7b7fc8a5eb4f02ef14588246bd111daf (patch)
tree0d9d28ca93ccbddb1f99cb02b88ed466e0ade481 /src/compiler/analyzer.zc
parenthistory: 43-stdlib notes point forward to zc0 no longer reserving u, m and d (diff)
parentmerge bounds checking (diff)
Merge branch 'main' into work/xref
Diffstat (limited to 'src/compiler/analyzer.zc')
-rw-r--r--src/compiler/analyzer.zc20
1 files changed, 20 insertions, 0 deletions
diff --git a/src/compiler/analyzer.zc b/src/compiler/analyzer.zc
index 8c63bdf..89713ff 100644
--- a/src/compiler/analyzer.zc
+++ b/src/compiler/analyzer.zc
@@ -500,6 +500,26 @@ int proven(int a, int ix) {
}
return 0;
}
+// i >= 0 and i < n for a fixed array of n elements, proved by a loop test
+// against a constant of at most n and a step of +1 (kw_for records the
+// constant as the array field, minus two, with -1 for the bound local)
+int proven_n(int ix, int n) {
+ int k = lsp, w;
+ while (k > loopbase) {
+ k--;
+ w = lpfact[k];
+ if (w >= 0 && p_iv(w) == ix && p_bd(w) == -1 && 0 - p_ar(w) - 2 <= n) return 1;
+ }
+ return 0;
+}
+// is the constant index xcval known to be inside the allocation f? the same
+// facts af_index warns from, so a possible failure is never called definite.
+int af_inrange(word f) {
+ int lower = 0; word base;
+ if (!f || !xconst || f[1] == 2 || f[0] < 0) return 0;
+ if (f[6]) { base = af_base(f); if (base[1] == 0 || base[10] < 0) return 0; if (f[14]) lower = f[13]; }
+ return xcval >= lower && xcval < f[0];
+}
// follow child links up to the local that really owns the object
int lroot(int i) {
while (lstate[i] == S_CHILD) i = lowner[i];