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

@@ -355,10 +355,11 @@
         int comparison;
         struct expression *expr;
         struct range_list *rl;
         int left;
         struct stree *stree;
+        struct stree *implied;
         struct db_implies_list *callbacks;
         int prev_return_id;
         int cull;
         int has_states;
         char *ret_str;

@@ -365,10 +366,21 @@
         struct smatch_state *ret_state;
         struct expression *var_expr;
         int handled;
 };
 
+static void set_implied_states(struct db_callback_info *db_info)
+{
+        struct sm_state *sm;
+
+        FOR_EACH_SM(db_info->implied, sm) {
+                __set_sm(sm);
+        } END_FOR_EACH_SM(sm);
+
+        free_stree(&db_info->implied);
+}
+
 static void store_return_state(struct db_callback_info *db_info, const char *ret_str, struct smatch_state *state)
 {
         db_info->ret_str = alloc_sname(ret_str),
         db_info->ret_state = state;
 }

@@ -458,10 +470,30 @@
         }
 
         return true;
 }
 
+static void set_fresh_mtag_returns(struct db_callback_info *db_info)
+{
+        struct expression *expr = db_info->expr->left;
+        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))));
+        state = get_mtag_return(db_info->expr, state);
+        if (!state)
+                return;
+
+        set_real_absolute(expr, state);
+        set_extra_expr_mod(expr, state);
+
+        db_info->ret_state = NULL;
+        db_info->ret_str = NULL;
+}
+
 static void set_return_assign_state(struct db_callback_info *db_info)
 {
         struct expression *expr = db_info->expr->left;
         struct smatch_state *state;
 

@@ -633,12 +665,12 @@
         value = argv[5];
 
         db_info->has_states = 1;
         if (db_info->prev_return_id != -1 && type == INTERNAL) {
                 set_other_side_state(db_info);
+                set_implied_states(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();
                 db_info->cull = 0;

@@ -670,18 +702,18 @@
 
         if (db_info->true_side) {
                 if (!possibly_true_rl(var_rl, comparison, ret_range))
                         return 0;
                 if (type == PARAM_LIMIT)
-                        param_limit_implications(db_info->expr, param, key, value);
+                        param_limit_implications(db_info->expr, param, key, value, &db_info->implied);
                 filter_by_comparison(&var_rl, comparison, ret_range);
                 filter_by_comparison(&ret_range, flip_comparison(comparison), var_rl);
         } else {
                 if (!possibly_false_rl(var_rl, comparison, ret_range))
                         return 0;
                 if (type == PARAM_LIMIT)
-                        param_limit_implications(db_info->expr, param, key, value);
+                        param_limit_implications(db_info->expr, param, key, value, &db_info->implied);
                 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);

@@ -742,10 +774,11 @@
         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);
+        set_implied_states(&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;

@@ -767,10 +800,11 @@
         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);
+        set_implied_states(&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;

@@ -891,10 +925,11 @@
         value = argv[5];
 
         if (db_info->prev_return_id != -1 && type == INTERNAL) {
                 call_ranged_return_hooks(db_info);
                 set_return_assign_state(db_info);
+                set_implied_states(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();

@@ -914,11 +949,11 @@
                 db_info->cull = 1;
                 return 0;
         }
 
         if (type == PARAM_LIMIT)
-                param_limit_implications(db_info->expr, param, key, value);
+                param_limit_implications(db_info->expr, param, key, value, &db_info->implied);
 
         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)));

@@ -928,10 +963,11 @@
                 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));
+                set_fresh_mtag_returns(db_info);
         }
 
         FOR_EACH_PTR(db_return_states_list, tmp) {
                 if (tmp->type == type)
                         tmp->callback(db_info->expr, param, key, value);

@@ -966,10 +1002,11 @@
                         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);
+        set_implied_states(&db_info);
         stree = __pop_fake_cur_stree();
         if (!db_info.cull)
                 merge_fake_stree(&db_info.stree, stree);
         free_stree(&stree);
 

@@ -1077,10 +1114,11 @@
         key = argv[4];
         value = argv[5];
 
         if (db_info->prev_return_id != -1 && type == INTERNAL) {
                 call_ranged_return_hooks(db_info);
+                set_implied_states(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();

@@ -1101,11 +1139,11 @@
                 db_info->cull = 1;
                 return 0;
         }
 
         if (type == PARAM_LIMIT)
-                param_limit_implications(db_info->expr, param, key, value);
+                param_limit_implications(db_info->expr, param, key, value, &db_info->implied);
 
         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) {

@@ -1152,10 +1190,11 @@
         __push_fake_cur_stree();
         __unnullify_path();
         sql_select_return_states("return_id, return, type, parameter, key, value",
                         expr, db_return_states_callback, &db_info);
         call_ranged_return_hooks(&db_info);
+        set_implied_states(&db_info);
         stree = __pop_fake_cur_stree();
         if (!db_info.cull)
                 merge_fake_stree(&db_info.stree, stree);
         free_stree(&stree);