aboutsummaryrefslogtreecommitdiffstats
path: root/interpret.h
diff options
context:
space:
mode:
authorKaz Kylheku <kaz@kylheku.com>2022-04-12 06:41:46 -0700
committerKaz Kylheku <kaz@kylheku.com>2022-04-12 06:41:46 -0700
commitc176b812d68da2284a221c8533a68a1aa290960b (patch)
tree7de45ed4e6920483fc093c15508ddfc0d242a295 /interpret.h
parent51ca241352218e6da8db10fe07c90e229a0bc1f8 (diff)
downloadegawk-c176b812d68da2284a221c8533a68a1aa290960b.tar.gz
egawk-c176b812d68da2284a221c8533a68a1aa290960b.tar.bz2
egawk-c176b812d68da2284a221c8533a68a1aa290960b.zip
@let: bug re-using previously array-typed location as scalar.
* awkgram.y (let_var_list): We must generate the Op_clear_var instruction even for variables which have initializers. Otherwise the initialization will bomb if the initializer is scalar, and the location we are re-using held an array previously. * interpret.h (r_interpret): Do not use the get_lhs function, which has complex semantics that depend on the existing type, and may initialize the value, as well as blow up for an array. We work directly with var->var_value. If var already has the new variable type, we have nothing to do. We now unref the prior value only if the prior type is Node_var, because prior array values and such don't support unref. * test/let1.awk: Extension of test case which reproduced this problem, plus additional test cases for coverage of the duplicated code in the Yacc grammar.
Diffstat (limited to 'interpret.h')
-rw-r--r--interpret.h21
1 files changed, 13 insertions, 8 deletions
diff --git a/interpret.h b/interpret.h
index 0dc261d6..f239406f 100644
--- a/interpret.h
+++ b/interpret.h
@@ -753,16 +753,21 @@ mod:
* initialized frame locations.
*/
NODE *var = pc->memory;
- lhs = get_lhs(var, false);
- /*
- * If it's already clear, nothing to do
- */
- if (*lhs != Nnull_string) {
- unref(*lhs);
- *lhs = dupnode(Nnull_string);
+ if (var->type != Node_var_new) {
+ NODETYPE prevtype = var->type;
+ var->type = Node_var_new;
+ var->flags &= MALLOC;
+
+ /*
+ * If it's already clear, nothing to do
+ */
+ if (var->var_value != Nnull_string) {
+ if (prevtype == Node_var)
+ unref(var->var_value);
+ var->var_value = dupnode(Nnull_string);
+ }
}
- var->type = Node_var_new;
}
break;