From 2c84ae489888754bc7dae310bd7c30e28c0a3f4f Mon Sep 17 00:00:00 2001 From: Bill Currie Date: Sun, 12 Dec 2010 15:37:26 +0900 Subject: [PATCH] Don't let casting in constfold increment users. This fixes Deek's temp notice. No new notices have shown up, so this should be the correct fix. The constant folding code no longer calls cast_expr directly, but rather uses an internal wrapper that decrements users after cast_expr increments it, resulting in a no-op. --- tools/qfcc/source/constfold.c | 37 +++++++++++++++++++++-------------- tools/qfcc/test/ptr-array.r | 13 ++++++++++++ 2 files changed, 35 insertions(+), 15 deletions(-) create mode 100644 tools/qfcc/test/ptr-array.r diff --git a/tools/qfcc/source/constfold.c b/tools/qfcc/source/constfold.c index c05fbb39a..31a3ce74c 100644 --- a/tools/qfcc/source/constfold.c +++ b/tools/qfcc/source/constfold.c @@ -58,6 +58,19 @@ internal_error (expr_t *e) abort (); } +static expr_t * +cf_cast_expr (type_t *type, expr_t *e) +{ + e = cast_expr (type, e); + // The expression of which this is a sub-expression has already + // incremented users, so we don't need cast_expr to do so again, + // however, since cast_expr does so unconditionally, we must undo + // the increment. + if (e && e->type == ex_uexpr && e->e.expr.op == 'C') + dec_users (e->e.expr.e1); + return e; +} + static int valid_op (int op, int *valid_ops) { @@ -151,13 +164,7 @@ convert_to_float (expr_t *e) case ex_uexpr: case ex_temp: case ex_block: - e = cast_expr (&type_float, e); - // The expression of which this is a sub-expression has already - // incremented users, so we don't need cast_expr to do so again, - // however, since cast_expr does so unconditionally, we must undo - // the increment. - if (e && e->type == ex_uexpr && e->e.expr.op == 'C') - dec_users (e->e.expr.e1); + e = cf_cast_expr (&type_float, e); return e; default: internal_error (e); @@ -182,14 +189,14 @@ do_op_float (int op, expr_t *e, expr_t *e1, expr_t *e2) // bind is backwards to assign (why did I do that? :P) if ((type = get_type (e2)) != &type_float) { //FIXME optimize casting a constant - e->e.expr.e1 = e1 = cast_expr (type, e1); + e->e.expr.e1 = e1 = cf_cast_expr (type, e1); } else if ((conv = convert_to_float (e1)) != e1) { e->e.expr.e1 = e1 = conv; } } else if (op == '=' || op == PAS) { if ((type = get_type (e1)) != &type_float) { //FIXME optimize casting a constant - e->e.expr.e2 = e2 = cast_expr (type, e2); + e->e.expr.e2 = e2 = cf_cast_expr (type, e2); } else if ((conv = convert_to_float (e2)) != e2) { e->e.expr.e2 = e2 = conv; } @@ -444,7 +451,7 @@ do_op_pointer (int op, expr_t *e, expr_t *e1, expr_t *e2) return type_mismatch (e1, e2, op); if ((op == '.' || op == '&') && get_type (e2) == &type_uinteger) { //FIXME should implement unsigned addressing - e->e.expr.e2 = cast_expr (&type_integer, e2); + e->e.expr.e2 = cf_cast_expr (&type_integer, e2); } return e; } @@ -643,7 +650,7 @@ convert_to_uinteger (expr_t *e) case ex_uexpr: case ex_temp: case ex_block: - return cast_expr (&type_uinteger, e); + return cf_cast_expr (&type_uinteger, e); default: internal_error (e); } @@ -670,26 +677,26 @@ do_op_uinteger (int op, expr_t *e, expr_t *e1, expr_t *e2) if (op == 'b') { // bind is backwards to assign (why did I do that? :P) if ((type = get_type (e2)) != &type_uinteger) { - e->e.expr.e1 = e1 = cast_expr (type, e1); + e->e.expr.e1 = e1 = cf_cast_expr (type, e1); } else if ((conv = convert_to_uinteger (e1)) != e1) { e->e.expr.e1 = e1 = conv; } } else if (op == '=' || op == PAS) { if ((type = get_type (e1)) != &type_uinteger) { - e->e.expr.e2 = e2 = cast_expr (type, e2); + e->e.expr.e2 = e2 = cf_cast_expr (type, e2); } else if ((conv = convert_to_uinteger (e2)) != e2) { e->e.expr.e2 = e2 = conv; } } else { if (get_type (e1) != &type_uinteger) { - e->e.expr.e1 = e1 = cast_expr (&type_uinteger, e1); + e->e.expr.e1 = e1 = cf_cast_expr (&type_uinteger, e1); } if (e2->type == ex_short) convert_short_uint (e2); if (e2->type == ex_integer) convert_int_uint (e2); if (get_type (e2) != &type_uinteger) { - e->e.expr.e2 = e2 = cast_expr (&type_uinteger, e2); + e->e.expr.e2 = e2 = cf_cast_expr (&type_uinteger, e2); } if ((conv = convert_to_uinteger (e2)) != e2) { e->e.expr.e2 = e2 = conv; diff --git a/tools/qfcc/test/ptr-array.r b/tools/qfcc/test/ptr-array.r new file mode 100644 index 000000000..07fe723e5 --- /dev/null +++ b/tools/qfcc/test/ptr-array.r @@ -0,0 +1,13 @@ +@interface foo +{ + unsigned count; + id []_objs; +} +@end + +@implementation foo +- (void) foofoo: (id) anObject +{ + _objs[count++] = anObject; +} +@end