mirror of
https://github.com/DarkPlacesEngine/gmqcc.git
synced 2025-01-18 22:31:36 +00:00
operator &~= must not cause the generated binstore to free the destination twice
This commit is contained in:
parent
1c9de6763f
commit
ec2ff09eff
3 changed files with 10 additions and 2 deletions
5
ast.c
5
ast.c
|
@ -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
2
ast.h
|
@ -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,
|
||||||
|
|
5
parser.c
5
parser.c
|
@ -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
|
||||||
|
|
Loading…
Reference in a new issue