From: Wolfgang (Blub) Bumiller Date: Sun, 25 Nov 2012 23:15:07 +0000 (+0100) Subject: operator &~= must not cause the generated binstore to free the destination twice X-Git-Tag: 0.1.9~209 X-Git-Url: https://git.rm.cloudns.org/?a=commitdiff_plain;h=ec2ff09eff11104ba0d5d4fea0bb04bd2f017f4c;p=xonotic%2Fgmqcc.git operator &~= must not cause the generated binstore to free the destination twice --- diff --git a/ast.c b/ast.c index fb58547..a622db6 100644 --- a/ast.c +++ b/ast.c @@ -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); diff --git a/ast.h b/ast.h index 29c3192..f1ca3c8 100644 --- a/ast.h +++ b/ast.h @@ -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, diff --git a/parser.c b/parser.c index 1268d03..ea84205 100644 --- a/parser.c +++ b/parser.c @@ -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