diff options
author | Al Viro <viro@ftp.linux.org.uk> | 2007-07-01 08:49:22 +0100 |
---|---|---|
committer | Josh Triplett <josh@freedesktop.org> | 2007-07-08 18:57:32 -0700 |
commit | c3aac8e1fd7cbfab1f4c87baeb4b57453720d77a (patch) | |
tree | 2edc01916eaf2c8964a5587df5ea1c2af225c484 /expand.c | |
parent | fix the comma handling in integer constant expressions (diff) | |
download | sparse-c3aac8e1fd7cbfab1f4c87baeb4b57453720d77a.tar.gz sparse-c3aac8e1fd7cbfab1f4c87baeb4b57453720d77a.tar.bz2 sparse-c3aac8e1fd7cbfab1f4c87baeb4b57453720d77a.zip |
first pass at null pointer constants
AFAICS, that should do null pointer constants right. We assign
special instance of void * (&null_ctype) to (void *)<zero integer
constant expression> and replace it with normal void * when we
don't want null pointer constant. is_zero_constant() checks if
we have an integer constant expression, does conservative expand
(i.e. instead of generating an error on 1/0, etc. leaves the
node unreplaced) and checks if we have reduced the sucker to
EXPR_VALUE[0] without comma taint.
Implemented all (AFAICS) special cases involving null pointer
constants; most changes in evaluate_compare() and evaluate_conditional().
Both are still incomplete; handling of qualifiers is still missing,
but that's a separate story.
Note that we get two new sets of warnings on the kernel build; one is
due to wrong size_t (handled in the next patch; didn't show up until
now since we didn't warn on comparison of pointers to incompatible
types) and another is a pile of warnings about integer 0 used as NULL
on
if (p == 0)
where p is a pointer. Additionally, there's an idiotic
(p>0)
in one place (again, p is a pointer). Bugger if I know how gcc doesn't
warn on that one, it's certainly a standard violation and bloody pointless
even as extension...
Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
Diffstat (limited to 'expand.c')
-rw-r--r-- | expand.c | 38 |
1 files changed, 27 insertions, 11 deletions
@@ -34,6 +34,7 @@ static int expand_expression(struct expression *); static int expand_statement(struct statement *); +static int conservative; static int expand_symbol_expression(struct expression *expr) { @@ -97,7 +98,7 @@ Int: expr->value = value & mask; // Stop here unless checking for truncation - if (!Wcast_truncate) + if (!Wcast_truncate || conservative) return; // Check if we dropped any bits.. @@ -138,10 +139,8 @@ Float: static int check_shift_count(struct expression *expr, struct symbol *ctype, unsigned int count) { - if (count >= ctype->bit_size) { - warning(expr->pos, "shift too big (%u) for type %s", count, show_typename(ctype)); - count &= ctype->bit_size-1; - } + warning(expr->pos, "shift too big (%u) for type %s", count, show_typename(ctype)); + count &= ctype->bit_size-1; return count; } @@ -163,8 +162,12 @@ static int simplify_int_binop(struct expression *expr, struct symbol *ctype) return 0; r = right->value; if (expr->op == SPECIAL_LEFTSHIFT || expr->op == SPECIAL_RIGHTSHIFT) { - r = check_shift_count(expr, ctype, r); - right->value = r; + if (r >= ctype->bit_size) { + if (conservative) + return 0; + r = check_shift_count(expr, ctype, r); + right->value = r; + } } if (left->type != EXPR_VALUE) return 0; @@ -257,10 +260,12 @@ static int simplify_int_binop(struct expression *expr, struct symbol *ctype) expr->taint = left->taint | right->taint; return 1; Div: - warning(expr->pos, "division by zero"); + if (!conservative) + warning(expr->pos, "division by zero"); return 0; Overflow: - warning(expr->pos, "constant integer operation overflow"); + if (!conservative) + warning(expr->pos, "constant integer operation overflow"); return 0; } @@ -340,7 +345,8 @@ static int simplify_float_binop(struct expression *expr) expr->fvalue = res; return 1; Div: - warning(expr->pos, "division by zero"); + if (!conservative) + warning(expr->pos, "division by zero"); return 0; } @@ -660,7 +666,8 @@ static int simplify_preop(struct expression *expr) return 1; Overflow: - warning(expr->pos, "constant integer operation overflow"); + if (!conservative) + warning(expr->pos, "constant integer operation overflow"); return 0; } @@ -1222,3 +1229,12 @@ long long const_expression_value(struct expression *expr) { return __get_expression_value(expr, 1); } + +int is_zero_constant(struct expression *expr) +{ + int saved = conservative; + conservative = 1; + expand_expression(expr); + conservative = saved; + return expr->type == EXPR_VALUE && !expr->value; +} |