aboutsummaryrefslogtreecommitdiffstats
path: root/awkgram.y
diff options
context:
space:
mode:
Diffstat (limited to 'awkgram.y')
-rw-r--r--awkgram.y25
1 files changed, 22 insertions, 3 deletions
diff --git a/awkgram.y b/awkgram.y
index 285c233a..423cf66b 100644
--- a/awkgram.y
+++ b/awkgram.y
@@ -1644,17 +1644,26 @@ let_var_list
}
| NAME ASSIGN exp
{
- add_let(in_function, $1);
+ bool is_reused_location = add_let(in_function, $1);
$1->opcode = Op_push;
$1->memory = variable($1->source_line, $1->lextok, Node_var_new);
$$ = list_append(mk_assignment(list_create($1), $3, $2),
instruction(Op_pop));
-
+ /* Even for initialized variables, we must emit the Op_clear_var
+ instruction. This is because the variable may previously have
+ been an array and is now being assigned as a scalar value.
+ the Op_clear_var will reset the type to allow that. */
+ if (in_loop || is_reused_location) {
+ INSTRUCTION *clr = instruction(Op_clear_var);
+ UPREF($1->memory);
+ clr->memory = $1->memory;
+ $$ = list_prepend($$, clr);
+ }
}
| let_var_list comma NAME ASSIGN exp
{
INSTRUCTION *assn;
- add_let(in_function, $3);
+ bool is_reused_location = add_let(in_function, $3);
$3->opcode = Op_push;
$3->memory = variable($3->source_line, $3->lextok, Node_var_new);
assn = list_append(mk_assignment(list_create($3), $5, $4),
@@ -1663,6 +1672,16 @@ let_var_list
$$ = assn;
else
$$ = list_merge($1, assn);
+ /* Even for initialized variables, we must emit the Op_clear_var
+ instruction. This is because the variable may previously have
+ been an array and is now being assigned as a scalar value.
+ the Op_clear_var will reset the type to allow that. */
+ if (in_loop || is_reused_location) {
+ INSTRUCTION *clr = instruction(Op_clear_var);
+ UPREF($3->memory);
+ clr->memory = $3->memory;
+ $$ = list_prepend($$, clr);
+ }
}
| error
{ $$ = NULL; }