about summary refs log tree commit diff
path: root/compile.c
diff options
context:
space:
mode:
authorNakidai <nakidai@disroot.org>2026-04-07 05:44:14 +0300
committerNakidai <nakidai@disroot.org>2026-04-07 05:50:45 +0300
commit1d142cd5f7668c0a2ec5b4b62ccc9ca58f9703e9 (patch)
treeabcd4f1b55f1756595976f15c263595f28b09f13 /compile.c
parent75a1470fd2270eca5f9772b6ed8ad7517eeb30d8 (diff)
downloadthac-1d142cd5f7668c0a2ec5b4b62ccc9ca58f9703e9.tar.gz
thac-1d142cd5f7668c0a2ec5b4b62ccc9ca58f9703e9.zip
Fix assignment HEAD master
Unconditional freeing of r here is wrong, since it could be a variable
Diffstat (limited to 'compile.c')
-rw-r--r--compile.c27
1 files changed, 10 insertions, 17 deletions
diff --git a/compile.c b/compile.c
index dc070ca..61aab05 100644
--- a/compile.c
+++ b/compile.c
@@ -51,7 +51,7 @@ rvar(struct node *node, struct scope *scope) {
 static struct val
 roper(struct node *node, struct scope *scope)
 {
-	struct val l, m, r, ref, val;
+	struct val l, m, r, ref, refl, refr, val;
 	struct scope *lscope;
 	vlong i, j;
 
@@ -99,23 +99,19 @@ roper(struct node *node, struct scope *scope)
 	UN(OINV, ~)
 #undef UN
 	break; case OASSIGN:
-	{
-		struct val shouldfree = nil;
-		struct var *var;
-
-		val = getval(VVAR, eval(node->noper.l, scope), scope, 0);
+		refl = getval(VVAR, eval(node->noper.l, scope), scope, 0);
 		lscope = scope;
-		i = findvar(val.name, &lscope);
-		if (i >= 0)
-			shouldfree = deref(val, scope);
+		i = findvar(refl.name, &lscope);
+		l = i >= 0 ? deref(refl, scope) : nil;
 
-		r = deref(eval(node->noper.r, scope), scope);
+		refr = eval(node->noper.r, scope);
+		r = deref(refr, scope);
 
 		/* it's fine to use scope here as it won't be used after */
-		assignvar(val.name, copyval(r), &scope);
-		freeval(shouldfree);
-		freeval(r);
-	}
+		assignvar(refl.name, copyval(r), &scope);
+		freeval(l);
+		if (refr.type == VVAR)
+			freeval(r);
 #define ASS(NAME, OPER) break; case NAME: \
 { \
 	ref = getval(VVAR, eval(node->noper.l, scope), scope, 0); \
@@ -217,8 +213,6 @@ roper(struct node *node, struct scope *scope)
 		if (ref.type == VARR)
 			freeval(ref);
 	break; case OCONCAT:
-	{
-		struct val refl, refr;
 		refl = eval(node->noper.l, scope);
 		l = getval(VARR, refl, scope, 1);
 		refr = eval(node->noper.r, scope);
@@ -239,7 +233,6 @@ roper(struct node *node, struct scope *scope)
 			freeval(refl);
 		if (refr.type == VARR)
 			freeval(refr);
-	}
 	break; case OLEN:
 		m = getval(VARR, eval(node->noper.m, scope), scope, 1);
 		val.num = m.len;