ranges: in cast_rl() sometimes it's better to just give up
authorDan Carpenter <dan.carpenter@oracle.com>
Fri, 15 Mar 2013 20:11:55 +0000 (15 23:11 +0300)
committerDan Carpenter <dan.carpenter@oracle.com>
Fri, 15 Mar 2013 20:11:55 +0000 (15 23:11 +0300)
The story here is that sometime people give you a very bogus range like
1-0 and in that case cast_rl() should just return the whole range because
it means we don't actually know anything.

I've tested this for a while and it doesn't seem to cause too many
problems.

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

index c4d3291..d2a7024 100644 (file)
@@ -740,17 +740,30 @@ static int rl_is_sane(struct range_list *rl)
 
        type = rl_type(rl);
        FOR_EACH_PTR(rl, tmp) {
-               if (type != tmp->min.type || type != tmp->max.type)
-                       return 0;
                if (!sval_fits(type, tmp->min))
                        return 0;
                if (!sval_fits(type, tmp->max))
                        return 0;
+               if (sval_cmp(tmp->min, tmp->max) > 0)
+                       return 0;
        } END_FOR_EACH_PTR(tmp);
 
        return 1;
 }
 
+static int rl_type_consistent(struct range_list *rl)
+{
+       struct data_range *tmp;
+       struct symbol *type;
+
+       type = rl_type(rl);
+       FOR_EACH_PTR(rl, tmp) {
+               if (type != tmp->min.type || type != tmp->max.type)
+                       return 0;
+       } END_FOR_EACH_PTR(tmp);
+       return 1;
+}
+
 struct range_list *cast_rl(struct symbol *type, struct range_list *rl)
 {
        struct data_range *tmp;
@@ -759,7 +772,11 @@ struct range_list *cast_rl(struct symbol *type, struct range_list *rl)
        if (!rl)
                return NULL;
 
-       if (!type || (rl_is_sane(rl) && type == rl_type(rl)))
+       if (!type)
+               return rl;
+       if (!rl_is_sane(rl))
+               return alloc_whole_rl(type);
+       if (type == rl_type(rl) && rl_type_consistent(rl))
                return rl;
 
        FOR_EACH_PTR(rl, tmp) {