aboutsummaryrefslogtreecommitdiff
path: root/src/compiler/analyzer.zc
diff options
context:
space:
mode:
Diffstat (limited to 'src/compiler/analyzer.zc')
-rw-r--r--src/compiler/analyzer.zc12
1 files changed, 6 insertions, 6 deletions
diff --git a/src/compiler/analyzer.zc b/src/compiler/analyzer.zc
index bf7dd9f..8ceaf09 100644
--- a/src/compiler/analyzer.zc
+++ b/src/compiler/analyzer.zc
@@ -703,15 +703,15 @@ word lafact_save() {
while (i < nloc) { b[2 + i - lbase] = lafact[i]; i++; }
return b;
}
-// after a loop: the locals its body left alone get back the allocation facts
-// the loop forgot. a body that might free (r[55]) still restores facts for
-// undirtied locals: a call that did not take the local cannot have freed it,
-// and proofs inside a later loop re-check r[55] for that loop. without this,
-// one touch() earlier in the function would permanently drop every length fact.
+// after a loop that frees nothing: the locals its body left alone get back the
+// allocation facts the loop forgot. a body with a call (r[55]) does not restore:
+// push/pop can change a growable length without "dirtying" the name, and a free
+// through an alias is possible; restoring would warn on a[99] after push with a
+// stale length 0.
int lafact_keep(word r, word b) {
int i;
- if (!b || dry || r[0]) return 0;
+ if (!b || dry || r[0] || r[55]) return 0;
i = b[0];
while (i < b[1] && i < nloc) { if (b[2 + i - b[0]] && !lafact[i] && !ldirty(r, lname[i]) && lclean(i)) lafact[i] = b[2 + i - b[0]]; i++; }
return 0;