extra: clear hard max if we are falling back to the type max on loops
authorDan Carpenter <dan.carpenter@oracle.com>
Fri, 23 Nov 2012 11:25:36 +0000 (23 14:25 +0300)
committerDan Carpenter <dan.carpenter@oracle.com>
Fri, 23 Nov 2012 11:25:36 +0000 (23 14:25 +0300)
The problem here is like this:
if (i = 0; i < some_var; i++) {
...
}

If we don't know the value of some_var then the inside the loop the value
is type_max - 1.  The false path is type_max.

The problem is that type_max is just a single value, and we single values
are automatically a hard max.  Which normally works, but in this case we
need to clear the hard max setting.

Signed-off-by: Dan Carpenter <dan.carpenter@oracle.com>
smatch_extra.c

index 50c3c11..ae3f8bb 100644 (file)
@@ -352,6 +352,7 @@ void __extra_pre_loop_hook_after(struct sm_state *sm,
 {
        struct expression *iter_expr;
        sval_t limit;
+       struct smatch_state *state;
 
        if (!iterator) {
                while_count_down_after(sm, condition);
@@ -369,7 +370,10 @@ void __extra_pre_loop_hook_after(struct sm_state *sm,
                limit = sval_binop(estate_min(sm->state), '-',
                                   sval_type_val(estate_type(sm->state), 1));
        }
-       set_extra_mod(sm->name, sm->sym, alloc_estate(limit));
+       state = alloc_estate(limit);
+       if (!estate_has_hard_max(sm->state))
+               estate_clear_hard_max(state);
+       set_extra_mod(sm->name, sm->sym, state);
 }
 
 static struct smatch_state *unmatched_state(struct sm_state *sm)