Print this page
11506 smatch resync
*** 137,146 ****
--- 137,156 ----
cb = alloc_fcall_back(RANGED_CALL, call_back, info);
cb->range = alloc_range_perm(ll_to_sval(start), ll_to_sval(end));
add_callback(func_hash, look_for, cb);
}
+ void return_implies_state_sval(const char *look_for, sval_t start, sval_t end,
+ implication_hook *call_back, void *info)
+ {
+ struct fcall_back *cb;
+
+ cb = alloc_fcall_back(RANGED_CALL, call_back, info);
+ cb->range = alloc_range_perm(start, end);
+ add_callback(func_hash, look_for, cb);
+ }
+
void select_return_states_hook(int type, return_implies_hook *callback)
{
struct return_implies_callback *cb = __alloc_return_implies_callback(0);
cb->type = type;
*** 244,253 ****
--- 254,264 ----
struct smatch_state *estate;
struct stree *tmp_stree;
struct stree *final_states = NULL;
struct range_list *handled_ranges = NULL;
struct call_back_list *same_range_call_backs = NULL;
+ struct range_list *rl;
int handled = 0;
if (!call_backs)
return 0;
*** 266,276 ****
same_range_call_backs = get_same_ranged_call_backs(call_backs, tmp->range);
call_ranged_call_backs(same_range_call_backs, fn, expr->right, expr);
__free_ptr_list((struct ptr_list **)&same_range_call_backs);
! estate = alloc_estate_range(tmp->range->min, tmp->range->max);
set_extra_mod(var_name, sym, expr->left, estate);
tmp_stree = __pop_fake_cur_stree();
merge_fake_stree(&final_states, tmp_stree);
free_stree(&tmp_stree);
--- 277,289 ----
same_range_call_backs = get_same_ranged_call_backs(call_backs, tmp->range);
call_ranged_call_backs(same_range_call_backs, fn, expr->right, expr);
__free_ptr_list((struct ptr_list **)&same_range_call_backs);
! rl = alloc_rl(tmp->range->min, tmp->range->max);
! rl = cast_rl(get_type(expr->left), rl);
! estate = alloc_estate_rl(rl);
set_extra_mod(var_name, sym, expr->left, estate);
tmp_stree = __pop_fake_cur_stree();
merge_fake_stree(&final_states, tmp_stree);
free_stree(&tmp_stree);
*** 360,370 ****
db_info->ret_state = state;
}
static bool fake_a_param_assignment(struct expression *expr, const char *return_str)
{
! struct expression *arg, *left, *right, *fake_assign;
char *p;
int param;
char buf[256];
char *str;
--- 373,383 ----
db_info->ret_state = state;
}
static bool fake_a_param_assignment(struct expression *expr, const char *return_str)
{
! struct expression *arg, *left, *right, *tmp, *fake_assign;
char *p;
int param;
char buf[256];
char *str;
*** 400,409 ****
--- 413,428 ----
*p = '\0';
arg = get_argument_from_call_expr(right->args, param);
if (!arg)
return false;
+
+ /* There should be a get_other_name() function which returns an expr */
+ tmp = get_assigned_expr(arg);
+ if (tmp)
+ arg = tmp;
+
/*
* This is a sanity check to prevent side effects from evaluating stuff
* twice.
*/
str = expr_to_chunk_sym_vsl(arg, NULL, NULL);
*** 419,430 ****
__split_expr(fake_assign);
__in_fake_parameter_assign--;
return true;
}
! static void set_return_state(struct expression *expr, struct db_callback_info *db_info)
{
struct smatch_state *state;
if (!db_info->ret_state)
return;
--- 438,450 ----
__split_expr(fake_assign);
__in_fake_parameter_assign--;
return true;
}
! static void set_return_assign_state(struct db_callback_info *db_info)
{
+ struct expression *expr = db_info->expr->left;
struct smatch_state *state;
if (!db_info->ret_state)
return;
*** 433,442 ****
--- 453,476 ----
db_info->ret_state = NULL;
fake_a_param_assignment(db_info->expr, db_info->ret_str);
db_info->ret_str = NULL;
}
+ static void set_other_side_state(struct db_callback_info *db_info)
+ {
+ struct expression *expr = db_info->var_expr;
+ struct smatch_state *state;
+
+ if (!db_info->ret_state)
+ return;
+
+ state = alloc_estate_rl(cast_rl(get_type(expr), clone_rl(estate_rl(db_info->ret_state))));
+ set_extra_expr_nomod(expr, state);
+ db_info->ret_state = NULL;
+ db_info->ret_str = NULL;
+ }
+
static void handle_ret_equals_param(char *ret_string, struct range_list *rl, struct expression *call)
{
char *str;
long long param;
struct expression *arg;
*** 559,586 ****
{
struct db_callback_info *db_info = _info;
struct range_list *var_rl = db_info->rl;
struct range_list *ret_range;
int type, param;
! char *key, *value;
struct return_implies_callback *tmp;
struct stree *stree;
int return_id;
int comparison;
if (argc != 6)
return 0;
return_id = atoi(argv[0]);
type = atoi(argv[2]);
param = atoi(argv[3]);
key = argv[4];
value = argv[5];
db_info->has_states = 1;
if (db_info->prev_return_id != -1 && type == INTERNAL) {
! set_return_state(db_info->var_expr, db_info);
stree = __pop_fake_cur_stree();
if (!db_info->cull)
merge_fake_stree(&db_info->stree, stree);
free_stree(&stree);
--- 593,621 ----
{
struct db_callback_info *db_info = _info;
struct range_list *var_rl = db_info->rl;
struct range_list *ret_range;
int type, param;
! char *ret_str, *key, *value;
struct return_implies_callback *tmp;
struct stree *stree;
int return_id;
int comparison;
if (argc != 6)
return 0;
return_id = atoi(argv[0]);
+ ret_str = argv[1];
type = atoi(argv[2]);
param = atoi(argv[3]);
key = argv[4];
value = argv[5];
db_info->has_states = 1;
if (db_info->prev_return_id != -1 && type == INTERNAL) {
! set_other_side_state(db_info);
stree = __pop_fake_cur_stree();
if (!db_info->cull)
merge_fake_stree(&db_info->stree, stree);
free_stree(&stree);
*** 601,611 ****
if (is_impossible_data(type, db_info->expr, param, key, value)) {
db_info->cull = 1;
return 0;
}
! call_results_to_rl(db_info->expr, get_type(strip_expr(db_info->expr)), argv[1], &ret_range);
ret_range = cast_rl(get_type(db_info->expr), ret_range);
if (!ret_range)
ret_range = alloc_whole_rl(get_type(db_info->expr));
comparison = db_info->comparison;
--- 636,646 ----
if (is_impossible_data(type, db_info->expr, param, key, value)) {
db_info->cull = 1;
return 0;
}
! call_results_to_rl(db_info->expr, get_type(strip_expr(db_info->expr)), ret_str, &ret_range);
ret_range = cast_rl(get_type(db_info->expr), ret_range);
if (!ret_range)
ret_range = alloc_whole_rl(get_type(db_info->expr));
comparison = db_info->comparison;
*** 626,642 ****
param_limit_implications(db_info->expr, param, key, value);
filter_by_comparison(&var_rl, negate_comparison(comparison), ret_range);
filter_by_comparison(&ret_range, flip_comparison(negate_comparison(comparison)), var_rl);
}
! handle_ret_equals_param(argv[1], ret_range, db_info->expr);
if (type == INTERNAL) {
set_state(-1, "unnull_path", NULL, &true_state);
! __add_return_comparison(strip_expr(db_info->expr), argv[1]);
! __add_return_to_param_mapping(db_info->expr, argv[1]);
! store_return_state(db_info, argv[1], alloc_estate_rl(clone_rl(var_rl)));
}
FOR_EACH_PTR(db_info->callbacks, tmp) {
if (tmp->type == type)
tmp->callback(db_info->expr, param, key, value);
--- 661,677 ----
param_limit_implications(db_info->expr, param, key, value);
filter_by_comparison(&var_rl, negate_comparison(comparison), ret_range);
filter_by_comparison(&ret_range, flip_comparison(negate_comparison(comparison)), var_rl);
}
! handle_ret_equals_param(ret_str, ret_range, db_info->expr);
if (type == INTERNAL) {
set_state(-1, "unnull_path", NULL, &true_state);
! __add_return_comparison(strip_expr(db_info->expr), ret_str);
! __add_return_to_param_mapping(db_info->expr, ret_str);
! store_return_state(db_info, ret_str, alloc_estate_rl(clone_rl(var_rl)));
}
FOR_EACH_PTR(db_info->callbacks, tmp) {
if (tmp->type == type)
tmp->callback(db_info->expr, param, key, value);
*** 685,700 ****
db_info.stree = NULL;
db_info.prev_return_id = -1;
__push_fake_cur_stree();
sql_select_return_states("return_id, return, type, parameter, key, value",
call_expr, db_compare_callback, &db_info);
! set_return_state(db_info.var_expr, &db_info);
stree = __pop_fake_cur_stree();
! if (!db_info.cull) {
! set_return_state(db_info.var_expr, &db_info);
merge_fake_stree(&db_info.stree, stree);
- }
free_stree(&stree);
true_states = db_info.stree;
if (!true_states && db_info.has_states) {
__push_fake_cur_stree();
set_path_impossible();
--- 720,733 ----
db_info.stree = NULL;
db_info.prev_return_id = -1;
__push_fake_cur_stree();
sql_select_return_states("return_id, return, type, parameter, key, value",
call_expr, db_compare_callback, &db_info);
! set_other_side_state(&db_info);
stree = __pop_fake_cur_stree();
! if (!db_info.cull)
merge_fake_stree(&db_info.stree, stree);
free_stree(&stree);
true_states = db_info.stree;
if (!true_states && db_info.has_states) {
__push_fake_cur_stree();
set_path_impossible();
*** 712,726 ****
db_info.prev_return_id = -1;
db_info.cull = 0;
__push_fake_cur_stree();
sql_select_return_states("return_id, return, type, parameter, key, value", call_expr,
db_compare_callback, &db_info);
stree = __pop_fake_cur_stree();
! if (!db_info.cull) {
! set_return_state(db_info.var_expr, &db_info);
merge_fake_stree(&db_info.stree, stree);
- }
free_stree(&stree);
false_states = db_info.stree;
if (!false_states && db_info.has_states) {
__push_fake_cur_stree();
set_path_impossible();
--- 745,758 ----
db_info.prev_return_id = -1;
db_info.cull = 0;
__push_fake_cur_stree();
sql_select_return_states("return_id, return, type, parameter, key, value", call_expr,
db_compare_callback, &db_info);
+ set_other_side_state(&db_info);
stree = __pop_fake_cur_stree();
! if (!db_info.cull)
merge_fake_stree(&db_info.stree, stree);
free_stree(&stree);
false_states = db_info.stree;
if (!false_states && db_info.has_states) {
__push_fake_cur_stree();
set_path_impossible();
*** 804,850 ****
fn = expr->fn->symbol_name->name;
call_backs = search_callback(func_hash, fn);
FOR_EACH_PTR(call_backs, tmp) {
! struct range_list *range_rl = NULL;
if (tmp->type != RANGED_CALL)
continue;
! add_range(&range_rl, tmp->range->min, tmp->range->max);
range_rl = cast_rl(estate_type(db_info->ret_state), range_rl);
! if (possibly_true_rl(range_rl, SPECIAL_EQUAL, estate_rl(db_info->ret_state))) {
! if (!possibly_true_rl(rl_invert(range_rl), SPECIAL_EQUAL, estate_rl(db_info->ret_state)))
(tmp->u.ranged)(fn, expr, db_info->expr, tmp->info);
- else
- db_info->handled = -1;
- }
} END_FOR_EACH_PTR(tmp);
}
static int db_assign_return_states_callback(void *_info, int argc, char **argv, char **azColName)
{
struct db_callback_info *db_info = _info;
struct range_list *ret_range;
int type, param;
! char *key, *value;
struct return_implies_callback *tmp;
struct stree *stree;
int return_id;
if (argc != 6)
return 0;
return_id = atoi(argv[0]);
type = atoi(argv[2]);
param = atoi(argv[3]);
key = argv[4];
value = argv[5];
if (db_info->prev_return_id != -1 && type == INTERNAL) {
call_ranged_return_hooks(db_info);
! set_return_state(db_info->expr->left, db_info);
stree = __pop_fake_cur_stree();
if (!db_info->cull)
merge_fake_stree(&db_info->stree, stree);
free_stree(&stree);
__push_fake_cur_stree();
--- 836,879 ----
fn = expr->fn->symbol_name->name;
call_backs = search_callback(func_hash, fn);
FOR_EACH_PTR(call_backs, tmp) {
! struct range_list *range_rl;
if (tmp->type != RANGED_CALL)
continue;
! range_rl = alloc_rl(tmp->range->min, tmp->range->max);
range_rl = cast_rl(estate_type(db_info->ret_state), range_rl);
! if (possibly_true_rl(range_rl, SPECIAL_EQUAL, estate_rl(db_info->ret_state)))
(tmp->u.ranged)(fn, expr, db_info->expr, tmp->info);
} END_FOR_EACH_PTR(tmp);
}
static int db_assign_return_states_callback(void *_info, int argc, char **argv, char **azColName)
{
struct db_callback_info *db_info = _info;
struct range_list *ret_range;
int type, param;
! char *ret_str, *key, *value;
struct return_implies_callback *tmp;
struct stree *stree;
int return_id;
if (argc != 6)
return 0;
return_id = atoi(argv[0]);
+ ret_str = argv[1];
type = atoi(argv[2]);
param = atoi(argv[3]);
key = argv[4];
value = argv[5];
if (db_info->prev_return_id != -1 && type == INTERNAL) {
call_ranged_return_hooks(db_info);
! set_return_assign_state(db_info);
stree = __pop_fake_cur_stree();
if (!db_info->cull)
merge_fake_stree(&db_info->stree, stree);
free_stree(&stree);
__push_fake_cur_stree();
*** 867,887 ****
if (type == PARAM_LIMIT)
param_limit_implications(db_info->expr, param, key, value);
db_info->handled = 1;
! call_results_to_rl(db_info->expr->right, get_type(strip_expr(db_info->expr->right)), argv[1], &ret_range);
if (!ret_range)
ret_range = alloc_whole_rl(get_type(strip_expr(db_info->expr->right)));
ret_range = cast_rl(get_type(db_info->expr->right), ret_range);
if (type == INTERNAL) {
set_state(-1, "unnull_path", NULL, &true_state);
! __add_return_comparison(strip_expr(db_info->expr->right), argv[1]);
! __add_comparison_info(db_info->expr->left, strip_expr(db_info->expr->right), argv[1]);
! __add_return_to_param_mapping(db_info->expr, argv[1]);
! store_return_state(db_info, argv[1], alloc_estate_rl(ret_range));
}
FOR_EACH_PTR(db_return_states_list, tmp) {
if (tmp->type == type)
tmp->callback(db_info->expr, param, key, value);
--- 896,916 ----
if (type == PARAM_LIMIT)
param_limit_implications(db_info->expr, param, key, value);
db_info->handled = 1;
! call_results_to_rl(db_info->expr->right, get_type(strip_expr(db_info->expr->right)), ret_str, &ret_range);
if (!ret_range)
ret_range = alloc_whole_rl(get_type(strip_expr(db_info->expr->right)));
ret_range = cast_rl(get_type(db_info->expr->right), ret_range);
if (type == INTERNAL) {
set_state(-1, "unnull_path", NULL, &true_state);
! __add_return_comparison(strip_expr(db_info->expr->right), ret_str);
! __add_comparison_info(db_info->expr->left, strip_expr(db_info->expr->right), ret_str);
! __add_return_to_param_mapping(db_info->expr, ret_str);
! store_return_state(db_info, ret_str, alloc_estate_rl(ret_range));
}
FOR_EACH_PTR(db_return_states_list, tmp) {
if (tmp->type == type)
tmp->callback(db_info->expr, param, key, value);
*** 915,925 ****
db_info.prev_return_id,
db_info.ret_state ? db_info.ret_state->name : "'<empty>'");
}
if (db_info.handled)
call_ranged_return_hooks(&db_info);
! set_return_state(db_info.expr->left, &db_info);
stree = __pop_fake_cur_stree();
if (!db_info.cull)
merge_fake_stree(&db_info.stree, stree);
free_stree(&stree);
--- 944,954 ----
db_info.prev_return_id,
db_info.ret_state ? db_info.ret_state->name : "'<empty>'");
}
if (db_info.handled)
call_ranged_return_hooks(&db_info);
! set_return_assign_state(&db_info);
stree = __pop_fake_cur_stree();
if (!db_info.cull)
merge_fake_stree(&db_info.stree, stree);
free_stree(&stree);
*** 1009,1028 ****
static int db_return_states_callback(void *_info, int argc, char **argv, char **azColName)
{
struct db_callback_info *db_info = _info;
struct range_list *ret_range;
int type, param;
! char *key, *value;
struct return_implies_callback *tmp;
struct stree *stree;
int return_id;
char buf[64];
if (argc != 6)
return 0;
return_id = atoi(argv[0]);
type = atoi(argv[2]);
param = atoi(argv[3]);
key = argv[4];
value = argv[5];
--- 1038,1058 ----
static int db_return_states_callback(void *_info, int argc, char **argv, char **azColName)
{
struct db_callback_info *db_info = _info;
struct range_list *ret_range;
int type, param;
! char *ret_str, *key, *value;
struct return_implies_callback *tmp;
struct stree *stree;
int return_id;
char buf[64];
if (argc != 6)
return 0;
return_id = atoi(argv[0]);
+ ret_str = argv[1];
type = atoi(argv[2]);
param = atoi(argv[3]);
key = argv[4];
value = argv[5];
*** 1051,1067 ****
}
if (type == PARAM_LIMIT)
param_limit_implications(db_info->expr, param, key, value);
! call_results_to_rl(db_info->expr, get_type(strip_expr(db_info->expr)), argv[1], &ret_range);
ret_range = cast_rl(get_type(db_info->expr), ret_range);
if (type == INTERNAL) {
set_state(-1, "unnull_path", NULL, &true_state);
! __add_return_comparison(strip_expr(db_info->expr), argv[1]);
! __add_return_to_param_mapping(db_info->expr, argv[1]);
}
FOR_EACH_PTR(db_return_states_list, tmp) {
if (tmp->type == type)
--- 1081,1097 ----
}
if (type == PARAM_LIMIT)
param_limit_implications(db_info->expr, param, key, value);
! call_results_to_rl(db_info->expr, get_type(strip_expr(db_info->expr)), ret_str, &ret_range);
ret_range = cast_rl(get_type(db_info->expr), ret_range);
if (type == INTERNAL) {
set_state(-1, "unnull_path", NULL, &true_state);
! __add_return_comparison(strip_expr(db_info->expr), ret_str);
! __add_return_to_param_mapping(db_info->expr, ret_str);
}
FOR_EACH_PTR(db_return_states_list, tmp) {
if (tmp->type == type)