Print this page
12166 resync smatch to 0.6.1-rc1-il-3


 102                 if (tmp->ident &&
 103                     strcmp(member_name, tmp->ident->name) == 0) {
 104                         return offset;
 105                 }
 106                 if (matches_anonymous_union(tmp, member_name))
 107                         return offset;
 108                 if (!(type_bits(tmp) % 8) && type_bits(tmp) / 8 == type_bytes(tmp))
 109                         offset += type_bytes(tmp);
 110                 else
 111                         bits += type_bits(tmp);
 112         } END_FOR_EACH_PTR(tmp);
 113         return -1;
 114 }
 115 
 116 int get_member_offset_from_deref(struct expression *expr)
 117 {
 118         struct symbol *type;
 119         struct ident *member;
 120         int offset;
 121 





 122         if (expr->type != EXPR_DEREF)  /* hopefully, this doesn't happen */
 123                 return -1;
 124 
 125         if (expr->member_offset >= 0)
 126                 return expr->member_offset;
 127 
 128         member = expr->member;
 129         if (!member)
 130                 return -1;
 131 
 132         type = get_type(expr->deref);
 133         if (type_is_ptr(type))
 134                 type = get_real_base_type(type);
 135         if (!type || type->type != SYM_STRUCT)
 136                 return -1;
 137 
 138         offset = get_member_offset(type, member->name);
 139         if (offset >= 0)
 140                 expr->member_offset = offset;
 141         return offset;


 185 
 186         /* no wrap around */
 187         max.uvalue = rl_max(orig).uvalue;
 188         if (max.uvalue > sval_type_max(&ptr_ctype).uvalue - offset) {
 189                 remove = sval_type_max(&ptr_ctype);
 190                 remove.uvalue -= offset;
 191                 orig = remove_range(orig, remove, max);
 192         }
 193 
 194         sval.type = &int_ctype;
 195         sval.value = offset;
 196 
 197         *rl = rl_binop(orig, '+', alloc_rl(sval, sval));
 198 }
 199 
 200 static struct range_list *where_allocated_rl(struct symbol *sym)
 201 {
 202         if (!sym)
 203                 return NULL;
 204 

 205         return alloc_rl(valid_ptr_min_sval, valid_ptr_max_sval);
 206 }
 207 


















 208 int get_address_rl(struct expression *expr, struct range_list **rl)
 209 {
 210         struct expression *unop;
 211 














 212         expr = strip_expr(expr);
 213         if (!expr)
 214                 return 0;
 215 
 216         if (expr->type == EXPR_STRING) {
 217                 *rl = alloc_rl(valid_ptr_min_sval, valid_ptr_max_sval);





 218                 return 1;
 219         }
 220 
 221         if (expr->type == EXPR_PREOP && expr->op == '&')




 222                 expr = strip_expr(expr->unop);
 223         else {
 224                 struct symbol *type;
 225 
 226                 type = get_type(expr);
 227                 if (!type || type->type != SYM_ARRAY)
 228                         return 0;
 229         }
 230 
 231         if (expr->type == EXPR_SYMBOL) {
 232                 *rl = where_allocated_rl(expr->symbol);
 233                 return 1;
 234         }
 235 
 236         if (is_array(expr)) {
 237                 struct expression *array;
 238                 struct expression *offset_expr;
 239                 struct range_list *array_rl, *offset_rl, *bytes_rl, *res;
 240                 struct symbol *type;
 241                 sval_t bytes;
 242 
 243                 array = get_array_base(expr);




 102                 if (tmp->ident &&
 103                     strcmp(member_name, tmp->ident->name) == 0) {
 104                         return offset;
 105                 }
 106                 if (matches_anonymous_union(tmp, member_name))
 107                         return offset;
 108                 if (!(type_bits(tmp) % 8) && type_bits(tmp) / 8 == type_bytes(tmp))
 109                         offset += type_bytes(tmp);
 110                 else
 111                         bits += type_bits(tmp);
 112         } END_FOR_EACH_PTR(tmp);
 113         return -1;
 114 }
 115 
 116 int get_member_offset_from_deref(struct expression *expr)
 117 {
 118         struct symbol *type;
 119         struct ident *member;
 120         int offset;
 121 
 122         /*
 123          * FIXME: This doesn't handle foo.u.bar correctly.
 124          *
 125          */
 126 
 127         if (expr->type != EXPR_DEREF)  /* hopefully, this doesn't happen */
 128                 return -1;
 129 
 130         if (expr->member_offset >= 0)
 131                 return expr->member_offset;
 132 
 133         member = expr->member;
 134         if (!member)
 135                 return -1;
 136 
 137         type = get_type(expr->deref);
 138         if (type_is_ptr(type))
 139                 type = get_real_base_type(type);
 140         if (!type || type->type != SYM_STRUCT)
 141                 return -1;
 142 
 143         offset = get_member_offset(type, member->name);
 144         if (offset >= 0)
 145                 expr->member_offset = offset;
 146         return offset;


 190 
 191         /* no wrap around */
 192         max.uvalue = rl_max(orig).uvalue;
 193         if (max.uvalue > sval_type_max(&ptr_ctype).uvalue - offset) {
 194                 remove = sval_type_max(&ptr_ctype);
 195                 remove.uvalue -= offset;
 196                 orig = remove_range(orig, remove, max);
 197         }
 198 
 199         sval.type = &int_ctype;
 200         sval.value = offset;
 201 
 202         *rl = rl_binop(orig, '+', alloc_rl(sval, sval));
 203 }
 204 
 205 static struct range_list *where_allocated_rl(struct symbol *sym)
 206 {
 207         if (!sym)
 208                 return NULL;
 209 
 210         /* This should just be the mtag if it's not on the stack */
 211         return alloc_rl(valid_ptr_min_sval, valid_ptr_max_sval);
 212 }
 213 
 214 static bool handle_fn_address(struct expression *expr, struct range_list **rl)
 215 {
 216         struct symbol *type;
 217 
 218         if (expr->type == EXPR_PREOP && expr->op == '&')
 219                 expr = strip_expr(expr->unop);
 220 
 221         if (expr->type != EXPR_SYMBOL)
 222                 return false;
 223 
 224         type = get_type(expr);
 225         if (!type || type->type != SYM_FN)
 226                 return false;
 227 
 228         *rl = alloc_rl(valid_ptr_min_sval, valid_ptr_max_sval);
 229         return true;
 230 }
 231 
 232 int get_address_rl(struct expression *expr, struct range_list **rl)
 233 {
 234         struct expression *unop;
 235 
 236         /*
 237          * Ugh...  This function is bad.  It doesn't work where it's supposed to
 238          * and it does more than it really should.  It shouldn't handle string
 239          * literals I think...
 240          *
 241          * There are several complications.  For arrays and functions the "&foo"
 242          * "foo" are equivalent.  But the problem is that we're also passing in
 243          * foo->array[] and foo->fn.
 244          *
 245          * Then, when we have foo->bar.baz.one.two; that needs to be handled
 246          * correctly but right now, it is not.
 247          *
 248          */
 249 
 250         expr = strip_expr(expr);
 251         if (!expr)
 252                 return 0;
 253 
 254         /*
 255          * For functions &fn and fn are equivalent.  I don't know if this is
 256          * really the right place to handle it, but let's just get it out of the
 257          * way for now.
 258          *
 259          */
 260         if (handle_fn_address(expr, rl))
 261                 return 1;

 262 
 263         /*
 264          * For arrays, &foo->array and foo->array are equivalent.
 265          *
 266          */
 267         if (expr->type == EXPR_PREOP && expr->op == '&') {
 268                 expr = strip_expr(expr->unop);
 269         } else {
 270                 struct symbol *type;
 271 
 272                 type = get_type(expr);
 273                 if (!type || type->type != SYM_ARRAY)
 274                         return 0;
 275         }
 276 
 277         if (expr->type == EXPR_SYMBOL) {
 278                 *rl = where_allocated_rl(expr->symbol);
 279                 return 1;
 280         }
 281 
 282         if (is_array(expr)) {
 283                 struct expression *array;
 284                 struct expression *offset_expr;
 285                 struct range_list *array_rl, *offset_rl, *bytes_rl, *res;
 286                 struct symbol *type;
 287                 sval_t bytes;
 288 
 289                 array = get_array_base(expr);