aboutsummaryrefslogtreecommitdiff
path: root/src/compiler
diff options
context:
space:
mode:
Diffstat (limited to 'src/compiler')
-rw-r--r--src/compiler/analyzer.zc5
1 files changed, 4 insertions, 1 deletions
diff --git a/src/compiler/analyzer.zc b/src/compiler/analyzer.zc
index a1588e8..839c1ef 100644
--- a/src/compiler/analyzer.zc
+++ b/src/compiler/analyzer.zc
@@ -1009,7 +1009,7 @@ int end_owner(int i) {
end_why = 0; end_whom = 0;
local_ended[i] = info[2]; local_end_info[i] = info; lstate[i] = S_DEAD;
while (j < nloc) {
- if (j != i && isalias(j) && lroot(j) == i) { local_ended[j] = info[2]; local_end_info[j] = info; lstate[j] = S_DEAD; }
+ if (j != i && lstate[j] == S_CHILD && lroot(j) == i) { local_ended[j] = info[2]; local_end_info[j] = info; lstate[j] = S_DEAD; } // aliases and owned children go with it
j++;
}
return 0;
@@ -1612,6 +1612,9 @@ int assigncheck(int k, int i, int rc) {
touch(i);
if (rc == C_FRESH) { emitown(i); return C_PLAIN; }
if (j < 0) return C_PLAIN;
+ // a back link: storing the container's own owner (or the container itself)
+ // into it. it stays a plain reference; ownership would form a cycle.
+ if (r == j) { touch(j); return C_PLAIN; }
js = lstate[j];
if (js == S_CHILD) cerrn(j, "already belongs to a container");
else if (js == S_BORROW) cerrn(j, "is borrowed and can't be stored");