From 2f20516480062187b433e07620f5df558481a068 Mon Sep 17 00:00:00 2001 From: Dan Carpenter Date: Tue, 24 Apr 2012 10:44:45 +0300 Subject: [PATCH] sparse: introduce get_expression_value_nomod() This is an ugly hack, of course. The problem is that I want to deal with EXPR_SIZEOF expressions but when I call get_implied_value() on one of these then Sparse turns it into an EXPR_VALUE behind my back. I would change it so that Sparse doesn't change sizeof expressions into value expressions, but Sparse relies on this behavior for some of its checks. Probably I should hunt down where that behavior is needed, and do an explicit call to evaluate_expression() there. Signed-off-by: Dan Carpenter --- expand.c | 32 ++++++++++++++++++++++++++++++++ expression.h | 1 + smatch_math.c | 2 +- 3 files changed, 34 insertions(+), 1 deletion(-) diff --git a/expand.c b/expand.c index b965dc35..0b4761ee 100644 --- a/expand.c +++ b/expand.c @@ -1224,6 +1224,38 @@ static long long __get_expression_value(struct expression *expr, int strict) return value; } +long long get_expression_value_nomod(struct expression *expr) +{ + long long value, mask; + struct symbol *ctype; + struct expression copy; + + if (!expr) + return 0; + memcpy(©, expr, sizeof(copy)); + ctype = evaluate_expression(©); + if (!ctype) { + expression_error(©, "bad constant expression type"); + return 0; + } + expand_expression(©); + if (copy.type != EXPR_VALUE) { + expression_error(©, "bad constant expression"); + return 0; + } + + value = copy.value; + mask = 1ULL << (ctype->bit_size-1); + + if (value & mask) { + while (ctype->type != SYM_BASETYPE) + ctype = ctype->ctype.base_type; + if (!(ctype->ctype.modifiers & MOD_UNSIGNED)) + value = value | mask | ~(mask-1); + } + return value; +} + long long get_expression_value(struct expression *expr) { return __get_expression_value(expr, 0); diff --git a/expression.h b/expression.h index da6ccac9..c937790e 100644 --- a/expression.h +++ b/expression.h @@ -168,6 +168,7 @@ struct expression { int is_zero_constant(struct expression *); long long get_expression_value(struct expression *); long long const_expression_value(struct expression *); +long long get_expression_value_nomod(struct expression *); /* Expression parsing */ struct token *parse_expression(struct token *token, struct expression **tree); diff --git a/smatch_math.c b/smatch_math.c index 0fbef222..b46bcce5 100644 --- a/smatch_math.c +++ b/smatch_math.c @@ -455,7 +455,7 @@ static long long _get_value(struct expression *expr, int *undefined, int implied break; case EXPR_PTRSIZEOF: case EXPR_SIZEOF: - ret = get_expression_value(expr); + ret = get_expression_value_nomod(expr); break; case EXPR_SYMBOL: if (get_const_value(expr, &ret)) -- 2.11.4.GIT