diff options
| author | Linus Torvalds <torvalds@penguin.transmeta.com> | 2003-04-04 16:28:05 -0700 |
|---|---|---|
| committer | Linus Torvalds <torvalds@ppc970.osdl.org> | 2005-04-07 21:00:12 -0700 |
| commit | 712f630a63f795a09cc0dba8096c13d208ca7039 (patch) | |
| tree | 678d71991dbf3bdff03a646b1bd271466c2c49a0 | |
| parent | bc5f5ac6db207545064aabf73ba3cde9622742f2 (diff) | |
| download | sparse-dev-712f630a63f795a09cc0dba8096c13d208ca7039.tar.gz | |
Evaluate conditional expressions with the gcc extension
(ie 'a ? : b' is equivalent to 'a ? a : b' modulo side
effects).
Simplify conditional expressions.
| -rw-r--r-- | evaluate.c | 51 |
1 files changed, 30 insertions, 21 deletions
@@ -589,29 +589,36 @@ static struct symbol *compatible_ptr_type(struct expression *left, struct expres static struct symbol * evaluate_conditional(struct expression *expr) { - struct symbol *ctype; - struct symbol *ltype = expr->cond_true->ctype; - struct symbol *rtype = expr->cond_false->ctype; + struct expression *cond, *true, *false; + struct symbol *ctype, *ltype, *rtype; - if (same_type(ltype, rtype)) { - expr->ctype = ltype; - return ltype; - } + cond = expr->conditional; + true = expr->cond_true ? : cond; + false = expr->cond_false; - ctype = compatible_integer_binop(expr, &expr->cond_true, &expr->cond_false); - if (ctype) { - expr->ctype = ctype; - return ctype; - } + ltype = true->ctype; + rtype = false->ctype; - ctype = compatible_ptr_type(expr->cond_true, expr->cond_false); - if (ctype) { - expr->ctype = ctype; - return ctype; + ctype = ltype; + if (!same_type(ltype, rtype)) { + ctype = compatible_integer_binop(expr, &true, &expr->cond_false); + if (!ctype) { + ctype = compatible_ptr_type(true, expr->cond_false); + if (!ctype) { + warn(expr->pos, "incompatible types in conditional expression"); + return NULL; + } + } } - warn(expr->pos, "incompatible types in conditional expression"); - return NULL; + /* Simplify conditional expression.. */ + if (cond->type == EXPR_VALUE) { + if (!cond->value) + true = false; + *expr = *true; + } + expr->ctype = ctype; + return ctype; } static int compatible_assignment_types(struct expression *expr, struct symbol *target, @@ -1176,9 +1183,11 @@ struct symbol *evaluate_expression(struct expression *expr) warn(expr->pos, "bitfield generated by parser"); return NULL; case EXPR_CONDITIONAL: - if (!evaluate_expression(expr->conditional) || - !evaluate_expression(expr->cond_true) || - !evaluate_expression(expr->cond_false)) + if (!evaluate_expression(expr->conditional)) + return NULL; + if (!evaluate_expression(expr->cond_false)) + return NULL; + if (expr->cond_true && !evaluate_expression(expr->cond_true)) return NULL; return evaluate_conditional(expr); case EXPR_STATEMENT: |
