operator &~= must not cause the generated binstore to free the destination twice

This commit is contained in:
Wolfgang (Blub) Bumiller 2012-11-26 00:15:07 +01:00
parent 1c9de6763f
commit ec2ff09eff
3 changed files with 10 additions and 2 deletions

5
ast.c
View file

@ -435,6 +435,8 @@ ast_binstore* ast_binstore_new(lex_ctx ctx, int storop, int op,
self->dest = left;
self->source = right;
self->keep_dest = false;
self->expression.vtype = left->expression.vtype;
if (left->expression.next) {
self->expression.next = ast_type_copy(ctx, left);
@ -451,7 +453,8 @@ ast_binstore* ast_binstore_new(lex_ctx ctx, int storop, int op,
void ast_binstore_delete(ast_binstore *self)
{
ast_unref(self->dest);
if (!self->keep_dest)
ast_unref(self->dest);
ast_unref(self->source);
ast_expression_delete((ast_expression*)self);
mem_d(self);

2
ast.h
View file

@ -234,6 +234,8 @@ struct ast_binstore_s
int opbin;
ast_expression *dest;
ast_expression *source;
/* for &~= which uses the destination in a binary in source we can use this */
bool keep_dest;
};
ast_binstore* ast_binstore_new(lex_ctx ctx,
int storeop,

View file

@ -485,6 +485,7 @@ static bool parser_sy_pop(parser_t *parser, shunt *sy)
ast_expression *exprs[3];
ast_block *blocks[3];
ast_value *asvalue[3];
ast_binstore *asbinstore;
size_t i, assignop, addop, subop;
qcint generated_op = 0;
@ -1141,7 +1142,9 @@ static bool parser_sy_pop(parser_t *parser, shunt *sy)
if (ast_istype(exprs[0], ast_value) && asvalue[0]->constant) {
parseerror(parser, "assignment to constant `%s`", asvalue[0]->name);
}
out = (ast_expression*)ast_binstore_new(ctx, assignop, INSTR_SUB_F, exprs[0], out);
asbinstore = ast_binstore_new(ctx, assignop, INSTR_SUB_F, exprs[0], out);
asbinstore->keep_dest = true;
out = (ast_expression*)asbinstore;
break;
}
#undef NotSameType