diff --git a/tools/qfcc/include/expr.h b/tools/qfcc/include/expr.h index 11c67663e..fffdf189f 100644 --- a/tools/qfcc/include/expr.h +++ b/tools/qfcc/include/expr.h @@ -58,4 +58,5 @@ expr_t *binary_expr (int op, expr_t *e1, expr_t *e2); expr_t *unary_expr (int op, expr_t *e); expr_t *function_expr (expr_t *e1, expr_t *e2); +def_t *emit_statement (opcode_t *op, def_t *var_a, def_t *var_b, def_t *var_c); void emit_expr (expr_t *e); diff --git a/tools/qfcc/source/expr.c b/tools/qfcc/source/expr.c index 6f8498f7e..17cbe9515 100644 --- a/tools/qfcc/source/expr.c +++ b/tools/qfcc/source/expr.c @@ -712,6 +712,18 @@ emit_assign_expr (expr_t *e) op = PR_Opcode_Find ("=", 5, def_a, def_b, def_b); emit_statement (op, def_b, def_a, 0); } else { + if (def_a->initialized) { + if (options.cow) { + int size = type_size [def_a->type->type]; + int ofs = PR_NewLocation (def_a->type); + memcpy (pr_globals + ofs, pr_globals + def_a->ofs, size); + def_a->ofs = ofs; + def_a->initialized = 0; + } else { + fprintf (stderr, "%s:%d: assignment to constant %s\n", + strings + e->file, e->line, def_a->name); + } + } def_b = emit_sub_expr (e->e.expr.e2, def_a); } return def_b; diff --git a/tools/qfcc/source/qc-parse.y b/tools/qfcc/source/qc-parse.y index 776cd9edd..1d79dc4dc 100644 --- a/tools/qfcc/source/qc-parse.y +++ b/tools/qfcc/source/qc-parse.y @@ -201,6 +201,13 @@ opt_initializer : /*empty*/ | '=' const { + if (pr_scope) { + def_t *imm = PR_ReuseConstant ($2, 0); + opcode_t *op = PR_Opcode_Find ("=", 5, imm, imm, current_def); + emit_statement (op, imm, current_def, 0); + } else { + current_def = PR_ReuseConstant ($2, current_def); + } } | '=' '#' const {