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->dest = left;
self->source = right; self->source = right;
self->keep_dest = false;
self->expression.vtype = left->expression.vtype; self->expression.vtype = left->expression.vtype;
if (left->expression.next) { if (left->expression.next) {
self->expression.next = ast_type_copy(ctx, left); 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) void ast_binstore_delete(ast_binstore *self)
{ {
ast_unref(self->dest); if (!self->keep_dest)
ast_unref(self->dest);
ast_unref(self->source); ast_unref(self->source);
ast_expression_delete((ast_expression*)self); ast_expression_delete((ast_expression*)self);
mem_d(self); mem_d(self);

2
ast.h
View file

@ -234,6 +234,8 @@ struct ast_binstore_s
int opbin; int opbin;
ast_expression *dest; ast_expression *dest;
ast_expression *source; 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, ast_binstore* ast_binstore_new(lex_ctx ctx,
int storeop, int storeop,

View file

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