Print this page
12724 update smatch to 0.6.1-rc1-il-5


 318         left_sym = expr_to_sym(left);
 319         right_sym = expr_to_sym(right);
 320         if (!left_sym || left_sym != right_sym)
 321                 return -1;
 322 
 323         left_offset = get_member_offset_from_deref(left);
 324         if (right->type == EXPR_SYMBOL)
 325                 right_offset = 0;
 326         else {
 327                 if (right->type != EXPR_PREOP || right->op != '&')
 328                         return -1;
 329                 right = strip_expr(right->unop);
 330                 right_offset = get_member_offset_from_deref(right);
 331         }
 332         if (left_offset < 0 || right_offset < 0)
 333                 return -1;
 334 
 335         return left_offset - right_offset;
 336 }
 337 





















 338 static bool handle_subtract_rl(struct expression *expr, int implied, int *recurse_cnt, struct range_list **res)
 339 {
 340         struct symbol *type;
 341         struct range_list *left_orig, *right_orig;
 342         struct range_list *left_rl, *right_rl;
 343         sval_t min, max, tmp;
 344         int comparison;
 345         int offset;
 346 
 347         type = get_type(expr);
 348 
 349         offset = handle_offset_subtraction(expr);
 350         if (offset >= 0) {
 351                 tmp.type = type;
 352                 tmp.value = offset;
 353 
 354                 *res = alloc_rl(tmp, tmp);
 355                 return true;
 356         }
 357 


 392                 break;
 393         case SPECIAL_EQUAL:
 394                 min = sval_type_val(type, 0);
 395                 max = sval_type_val(type, 0);
 396                 break;
 397         case '<':
 398         case SPECIAL_UNSIGNED_LT:
 399                 max = sval_type_val(type, -1);
 400                 break;
 401         case SPECIAL_LTE:
 402         case SPECIAL_UNSIGNED_LTE:
 403                 max = sval_type_val(type, 0);
 404                 break;
 405         default:
 406                 if (!left_orig || !right_orig)
 407                         return false;
 408                 *res = rl_binop(left_rl, '-', right_rl);
 409                 return true;
 410         }
 411 
 412         if (!sval_binop_overflows(rl_min(left_rl), '-', rl_max(right_rl))) {

 413                 tmp = sval_binop(rl_min(left_rl), '-', rl_max(right_rl));
 414                 if (sval_cmp(tmp, min) > 0)
 415                         min = tmp;
 416         }
 417 
 418         if (!sval_is_max(rl_max(left_rl))) {
 419                 tmp = sval_binop(rl_max(left_rl), '-', rl_min(right_rl));
 420                 if (sval_cmp(tmp, max) < 0)
 421                         max = tmp;
 422         }
 423 
 424         if (sval_is_min(min) && sval_is_max(max))
 425                 return false;
 426 
 427         *res = cast_rl(type, alloc_rl(min, max));
 428         return true;
 429 }
 430 
 431 static bool handle_mod_rl(struct expression *expr, int implied, int *recurse_cnt, struct range_list **res)
 432 {


1198 
1199         if (sym_name_is("__builtin_constant_p", expr->fn))
1200                 return handle_builtin_constant_p(expr, implied, recurse_cnt, res_sval);
1201 
1202         if (sym_name_is("__builtin_choose_expr", expr->fn))
1203                 return handle__builtin_choose_expr(expr, implied, recurse_cnt, res, res_sval);
1204 
1205         if (sym_name_is("__builtin_expect", expr->fn) ||
1206             sym_name_is("__builtin_bswap16", expr->fn) ||
1207             sym_name_is("__builtin_bswap32", expr->fn) ||
1208             sym_name_is("__builtin_bswap64", expr->fn)) {
1209                 struct expression *arg;
1210 
1211                 arg = get_argument_from_call_expr(expr->args, 0);
1212                 return get_rl_sval(arg, implied, recurse_cnt, res, res_sval);
1213         }
1214 
1215         if (sym_name_is("strlen", expr->fn))
1216                 return handle_strlen(expr, implied, recurse_cnt, res, res_sval);
1217 
1218         if (implied == RL_EXACT || implied == RL_HARD || implied == RL_FUZZY)
1219                 return false;
1220 
1221         if (custom_handle_variable) {
1222                 rl = custom_handle_variable(expr);
1223                 if (rl) {
1224                         *res = rl;
1225                         return true;
1226                 }
1227         }
1228 
1229         /* Ugh...  get_implied_return() sets *rl to NULL on failure */
1230         if (get_implied_return(expr, &rl)) {
1231                 *res = rl;
1232                 return true;
1233         }
1234         rl = db_return_vals(expr);
1235         if (rl) {
1236                 *res = rl;
1237                 return true;
1238         }




 318         left_sym = expr_to_sym(left);
 319         right_sym = expr_to_sym(right);
 320         if (!left_sym || left_sym != right_sym)
 321                 return -1;
 322 
 323         left_offset = get_member_offset_from_deref(left);
 324         if (right->type == EXPR_SYMBOL)
 325                 right_offset = 0;
 326         else {
 327                 if (right->type != EXPR_PREOP || right->op != '&')
 328                         return -1;
 329                 right = strip_expr(right->unop);
 330                 right_offset = get_member_offset_from_deref(right);
 331         }
 332         if (left_offset < 0 || right_offset < 0)
 333                 return -1;
 334 
 335         return left_offset - right_offset;
 336 }
 337 
 338 static bool max_is_unknown_max(struct range_list *rl)
 339 {
 340         /*
 341          * The issue with this code is that we had:
 342          * if (foo > 1) return 1 - foo;
 343          * Ideally we would say that returns s32min-(-1) but what Smatch
 344          * was saying was that the lowest possible value was "1 - INT_MAX"
 345          *
 346          * My solution is to ignore max values for int or larger.  I keep
 347          * the max for shorts etc, because those might be worthwhile.
 348          *
 349          * The problem with just returning 1 - INT_MAX is that that is
 350          * treated as useful information but s32min is treated as basically
 351          * unknown.
 352          */
 353 
 354         if (type_bits(rl_type(rl)) < 31)
 355                 return false;
 356         return sval_is_max(rl_max(rl));
 357 }
 358 
 359 static bool handle_subtract_rl(struct expression *expr, int implied, int *recurse_cnt, struct range_list **res)
 360 {
 361         struct symbol *type;
 362         struct range_list *left_orig, *right_orig;
 363         struct range_list *left_rl, *right_rl;
 364         sval_t min, max, tmp;
 365         int comparison;
 366         int offset;
 367 
 368         type = get_type(expr);
 369 
 370         offset = handle_offset_subtraction(expr);
 371         if (offset >= 0) {
 372                 tmp.type = type;
 373                 tmp.value = offset;
 374 
 375                 *res = alloc_rl(tmp, tmp);
 376                 return true;
 377         }
 378 


 413                 break;
 414         case SPECIAL_EQUAL:
 415                 min = sval_type_val(type, 0);
 416                 max = sval_type_val(type, 0);
 417                 break;
 418         case '<':
 419         case SPECIAL_UNSIGNED_LT:
 420                 max = sval_type_val(type, -1);
 421                 break;
 422         case SPECIAL_LTE:
 423         case SPECIAL_UNSIGNED_LTE:
 424                 max = sval_type_val(type, 0);
 425                 break;
 426         default:
 427                 if (!left_orig || !right_orig)
 428                         return false;
 429                 *res = rl_binop(left_rl, '-', right_rl);
 430                 return true;
 431         }
 432 
 433         if (!max_is_unknown_max(right_rl) &&
 434             !sval_binop_overflows(rl_min(left_rl), '-', rl_max(right_rl))) {
 435                 tmp = sval_binop(rl_min(left_rl), '-', rl_max(right_rl));
 436                 if (sval_cmp(tmp, min) > 0)
 437                         min = tmp;
 438         }
 439 
 440         if (!sval_is_max(rl_max(left_rl))) {
 441                 tmp = sval_binop(rl_max(left_rl), '-', rl_min(right_rl));
 442                 if (sval_cmp(tmp, max) < 0)
 443                         max = tmp;
 444         }
 445 
 446         if (sval_is_min(min) && sval_is_max(max))
 447                 return false;
 448 
 449         *res = cast_rl(type, alloc_rl(min, max));
 450         return true;
 451 }
 452 
 453 static bool handle_mod_rl(struct expression *expr, int implied, int *recurse_cnt, struct range_list **res)
 454 {


1220 
1221         if (sym_name_is("__builtin_constant_p", expr->fn))
1222                 return handle_builtin_constant_p(expr, implied, recurse_cnt, res_sval);
1223 
1224         if (sym_name_is("__builtin_choose_expr", expr->fn))
1225                 return handle__builtin_choose_expr(expr, implied, recurse_cnt, res, res_sval);
1226 
1227         if (sym_name_is("__builtin_expect", expr->fn) ||
1228             sym_name_is("__builtin_bswap16", expr->fn) ||
1229             sym_name_is("__builtin_bswap32", expr->fn) ||
1230             sym_name_is("__builtin_bswap64", expr->fn)) {
1231                 struct expression *arg;
1232 
1233                 arg = get_argument_from_call_expr(expr->args, 0);
1234                 return get_rl_sval(arg, implied, recurse_cnt, res, res_sval);
1235         }
1236 
1237         if (sym_name_is("strlen", expr->fn))
1238                 return handle_strlen(expr, implied, recurse_cnt, res, res_sval);
1239 
1240         if (implied == RL_EXACT || implied == RL_HARD)
1241                 return false;
1242 
1243         if (custom_handle_variable) {
1244                 rl = custom_handle_variable(expr);
1245                 if (rl) {
1246                         *res = rl;
1247                         return true;
1248                 }
1249         }
1250 
1251         /* Ugh...  get_implied_return() sets *rl to NULL on failure */
1252         if (get_implied_return(expr, &rl)) {
1253                 *res = rl;
1254                 return true;
1255         }
1256         rl = db_return_vals(expr);
1257         if (rl) {
1258                 *res = rl;
1259                 return true;
1260         }