]> git.rm.cloudns.org Git - xonotic/gmqcc.git/commitdiff
operator &~= must not cause the generated binstore to free the destination twice
authorWolfgang (Blub) Bumiller <blub@speed.at>
Sun, 25 Nov 2012 23:15:07 +0000 (00:15 +0100)
committerWolfgang (Blub) Bumiller <blub@speed.at>
Sun, 25 Nov 2012 23:15:07 +0000 (00:15 +0100)
ast.c
ast.h
parser.c

diff --git a/ast.c b/ast.c
index fb58547a6bfd965eee5698b95b9945984913e30b..a622db649953e4c540844ace93e3c7abb5b4fd6a 100644 (file)
--- 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 29c3192df4acd1c1ecfbbeb18870481c0d36e66c..f1ca3c8d7d6c33c48e9de6ce2a11ad10c83a4f5b 100644 (file)
--- 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,
index 1268d03a5839245addbdf23df30eff0efbd2086b..ea84205f6e7a59ab54dab15590b0d7d49539862a 100644 (file)
--- 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