[qfcc] Expose l-value checking

Needed for assignment chains.
This commit is contained in:
Bill Currie 2020-03-14 17:45:54 +09:00
parent 7d5644e055
commit eca976e5ae
2 changed files with 22 additions and 12 deletions

View file

@ -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);

View file

@ -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 *