diff --git a/tools/qfcc/include/expr.h b/tools/qfcc/include/expr.h index 0efc998ba..39e405622 100644 --- a/tools/qfcc/include/expr.h +++ b/tools/qfcc/include/expr.h @@ -710,6 +710,7 @@ expr_t *build_for_statement (expr_t *init, expr_t *test, expr_t *next, expr_t *break_label, expr_t *continue_label); expr_t *build_state_expr (expr_t *e); expr_t *think_expr (struct symbol_s *think_sym); +int is_lvalue (const expr_t *expr) __attribute__((pure)); expr_t *assign_expr (expr_t *dst, expr_t *src); expr_t *cast_expr (struct type_s *t, expr_t *e); diff --git a/tools/qfcc/source/expr_assign.c b/tools/qfcc/source/expr_assign.c index 465746983..88d45ad7b 100644 --- a/tools/qfcc/source/expr_assign.c +++ b/tools/qfcc/source/expr_assign.c @@ -81,8 +81,8 @@ check_assign_logic_precedence (expr_t *dst, expr_t *src) return 0; } -static expr_t * -check_valid_lvalue (expr_t *expr) +int +is_lvalue (const expr_t *expr) { switch (expr->type) { case ex_symbol: @@ -90,7 +90,7 @@ check_valid_lvalue (expr_t *expr) case sy_name: break; case sy_var: - return 0; + return 1; case sy_const: break; case sy_type: @@ -106,21 +106,21 @@ check_valid_lvalue (expr_t *expr) } break; case ex_temp: - return 0; + return 1; case ex_expr: if (expr->e.expr.op == '.') { - return 0; + return 1; } if (expr->e.expr.op == 'A') { - return check_valid_lvalue (expr->e.expr.e1); + return is_lvalue (expr->e.expr.e1); } break; case ex_uexpr: if (expr->e.expr.op == '.') { - return 0; + return 1; } if (expr->e.expr.op == 'A') { - return check_valid_lvalue (expr->e.expr.e1); + return is_lvalue (expr->e.expr.e1); } break; case ex_memset: @@ -136,11 +136,20 @@ check_valid_lvalue (expr_t *expr) case ex_error: break; } - if (options.traditional) { - warning (expr, "invalid lvalue in assignment"); - return 0; + return 0; +} + +static expr_t * +check_valid_lvalue (expr_t *expr) +{ + if (!is_lvalue (expr)) { + if (options.traditional) { + warning (expr, "invalid lvalue in assignment"); + return 0; + } + return error (expr, "invalid lvalue in assignment"); } - return error (expr, "invalid lvalue in assignment"); + return 0; } static expr_t *