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 }
|