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


  19  * smatch_extra.c is supposed to track the value of every variable.
  20  *
  21  */
  22 
  23 #define _GNU_SOURCE
  24 #include <string.h>
  25 
  26 #include <stdlib.h>
  27 #include <errno.h>
  28 #ifndef __USE_ISOC99
  29 #define __USE_ISOC99
  30 #endif
  31 #include <limits.h>
  32 #include "parse.h"
  33 #include "smatch.h"
  34 #include "smatch_slist.h"
  35 #include "smatch_extra.h"
  36 
  37 static int my_id;
  38 static int link_id;
  39 extern int check_assigned_expr_id;
  40 
  41 static void match_link_modify(struct sm_state *sm, struct expression *mod_expr);
  42 
  43 struct string_list *__ignored_macros = NULL;
  44 int in_warn_on_macro(void)
  45 {
  46         struct statement *stmt;
  47         char *tmp;
  48         char *macro;
  49 
  50         stmt = get_current_statement();
  51         if (!stmt)
  52                 return 0;
  53         macro = get_macro_name(stmt->pos);
  54         if (!macro)
  55                 return 0;
  56 
  57         FOR_EACH_PTR(__ignored_macros, tmp) {
  58                 if (!strcmp(tmp, macro))
  59                         return 1;


 155                         if (tmp->ident)
 156                                 member_expr = member_expression(member_expr, '.', tmp->ident);
 157                         member_expr = member_expression(member_expr, expr->op, inner->ident);
 158                         member_name = expr_to_var(member_expr);
 159                         if (!member_name)
 160                                 continue;
 161                         new_type = get_real_base_type(inner);
 162                         new = alloc_estate_rl(cast_rl(new_type, estate_rl(state)));
 163                         set_extra_mod_helper(member_name, sym, member_expr, new);
 164                         free_string(member_name);
 165                 } END_FOR_EACH_PTR(inner);
 166         } END_FOR_EACH_PTR(tmp);
 167 
 168 done:
 169         in_recurse = false;
 170 }
 171 
 172 static bool in_param_set;
 173 void set_extra_mod_helper(const char *name, struct symbol *sym, struct expression *expr, struct smatch_state *state)
 174 {


 175         if (!expr)
 176                 expr = gen_expression_from_name_sym(name, sym);
 177         remove_from_equiv(name, sym);
 178         set_union_info(name, sym, expr, state);
 179         call_extra_mod_hooks(name, sym, expr, state);



 180         update_mtag_data(expr, state);
 181         if (in_param_set &&
 182             estate_is_unknown(state) && !get_state(SMATCH_EXTRA, name, sym))
 183                 return;
 184         set_state(SMATCH_EXTRA, name, sym, state);
 185 }
 186 
 187 static void set_extra_nomod_helper(const char *name, struct symbol *sym, struct expression *expr, struct smatch_state *state)
 188 {
 189         call_extra_nomod_hooks(name, sym, expr, state);
 190         set_state(SMATCH_EXTRA, name, sym, state);
 191 }
 192 
 193 static char *get_pointed_at(const char *name, struct symbol *sym, struct symbol **new_sym)
 194 {
 195         struct expression *assigned;
 196 
 197         /*
 198          * Imagine we have an assignment: "foo = &addr;" then the other name
 199          * of "*foo" is addr.


2783                 }
2784                 state = get_state_expr(SMATCH_EXTRA, arg);
2785                 if (!estate_get_single_value(state, &dummy) && estate_has_hard_max(state)) {
2786                         sql_insert_caller_info(expr, HARD_MAX, i, "$",
2787                                                sval_to_str(estate_max(state)));
2788                 }
2789                 if (estate_has_fuzzy_max(state)) {
2790                         sql_insert_caller_info(expr, FUZZY_MAX, i, "$",
2791                                                sval_to_str(estate_get_fuzzy_max(state)));
2792                 }
2793                 i++;
2794         } END_FOR_EACH_PTR(arg);
2795 }
2796 
2797 static void set_param_value(const char *name, struct symbol *sym, char *key, char *value)
2798 {
2799         struct expression *expr;
2800         struct range_list *rl = NULL;
2801         struct smatch_state *state;
2802         struct symbol *type;
2803         char fullname[256];
2804         char *key_orig = key;
2805         bool add_star = false;
2806         sval_t dummy;
2807 
2808         if (key[0] == '*') {
2809                 add_star = true;
2810                 key++;
2811         }
2812 
2813         snprintf(fullname, 256, "%s%s%s", add_star ? "*" : "", name, key + 1);
2814 
2815         expr = symbol_expression(sym);




2816         type = get_member_type_from_key(expr, key_orig);
2817         str_to_rl(type, value, &rl);
2818         state = alloc_estate_rl(rl);
2819         if (estate_get_single_value(state, &dummy))
2820                 estate_set_hard_max(state);
2821         set_state(SMATCH_EXTRA, fullname, sym, state);
2822 }
2823 
2824 static void set_param_fuzzy_max(const char *name, struct symbol *sym, char *key, char *value)
2825 {

2826         struct range_list *rl = NULL;
2827         struct smatch_state *state;
2828         struct symbol *type;
2829         char fullname[256];
2830         sval_t max;
2831 
2832         if (strcmp(key, "*$") == 0)
2833                 snprintf(fullname, sizeof(fullname), "*%s", name);
2834         else if (strncmp(key, "$", 1) == 0)
2835                 snprintf(fullname, 256, "%s%s", name, key + 1);
2836         else
2837                 return;
2838 
2839         state = get_state(SMATCH_EXTRA, fullname, sym);
2840         if (!state)
2841                 return;
2842         type = estate_type(state);
2843         str_to_rl(type, value, &rl);
2844         if (!rl_to_sval(rl, &max))
2845                 return;
2846         estate_set_fuzzy_max(state, max);
2847 }
2848 
2849 static void set_param_hard_max(const char *name, struct symbol *sym, char *key, char *value)
2850 {
2851         struct smatch_state *state;
2852         char fullname[256];

2853 
2854         if (strcmp(key, "*$") == 0)
2855                 snprintf(fullname, sizeof(fullname), "*%s", name);
2856         else if (strncmp(key, "$", 1) == 0)
2857                 snprintf(fullname, 256, "%s%s", name, key + 1);
2858         else
2859                 return;
2860 
2861         state = get_state(SMATCH_EXTRA, fullname, sym);
2862         if (!state)
2863                 return;
2864         estate_set_hard_max(state);
2865 }
2866 
2867 struct sm_state *get_extra_sm_state(struct expression *expr)
2868 {
2869         char *name;
2870         struct symbol *sym;
2871         struct sm_state *ret = NULL;
2872 
2873         name = expr_to_known_chunk_sym(expr, &sym);
2874         if (!name)
2875                 goto free;
2876 
2877         ret = get_sm_state(SMATCH_EXTRA, name, sym);
2878 free:




  19  * smatch_extra.c is supposed to track the value of every variable.
  20  *
  21  */
  22 
  23 #define _GNU_SOURCE
  24 #include <string.h>
  25 
  26 #include <stdlib.h>
  27 #include <errno.h>
  28 #ifndef __USE_ISOC99
  29 #define __USE_ISOC99
  30 #endif
  31 #include <limits.h>
  32 #include "parse.h"
  33 #include "smatch.h"
  34 #include "smatch_slist.h"
  35 #include "smatch_extra.h"
  36 
  37 static int my_id;
  38 static int link_id;

  39 
  40 static void match_link_modify(struct sm_state *sm, struct expression *mod_expr);
  41 
  42 struct string_list *__ignored_macros = NULL;
  43 int in_warn_on_macro(void)
  44 {
  45         struct statement *stmt;
  46         char *tmp;
  47         char *macro;
  48 
  49         stmt = get_current_statement();
  50         if (!stmt)
  51                 return 0;
  52         macro = get_macro_name(stmt->pos);
  53         if (!macro)
  54                 return 0;
  55 
  56         FOR_EACH_PTR(__ignored_macros, tmp) {
  57                 if (!strcmp(tmp, macro))
  58                         return 1;


 154                         if (tmp->ident)
 155                                 member_expr = member_expression(member_expr, '.', tmp->ident);
 156                         member_expr = member_expression(member_expr, expr->op, inner->ident);
 157                         member_name = expr_to_var(member_expr);
 158                         if (!member_name)
 159                                 continue;
 160                         new_type = get_real_base_type(inner);
 161                         new = alloc_estate_rl(cast_rl(new_type, estate_rl(state)));
 162                         set_extra_mod_helper(member_name, sym, member_expr, new);
 163                         free_string(member_name);
 164                 } END_FOR_EACH_PTR(inner);
 165         } END_FOR_EACH_PTR(tmp);
 166 
 167 done:
 168         in_recurse = false;
 169 }
 170 
 171 static bool in_param_set;
 172 void set_extra_mod_helper(const char *name, struct symbol *sym, struct expression *expr, struct smatch_state *state)
 173 {
 174         struct expression *faked;
 175 
 176         if (!expr)
 177                 expr = gen_expression_from_name_sym(name, sym);
 178         remove_from_equiv(name, sym);
 179         set_union_info(name, sym, expr, state);
 180         call_extra_mod_hooks(name, sym, expr, state);
 181         faked = get_faked_expression();
 182         if (!faked ||
 183             (faked->type == EXPR_ASSIGNMENT && is_fresh_alloc(faked->right)))
 184                 update_mtag_data(expr, state);
 185         if (in_param_set &&
 186             estate_is_unknown(state) && !get_state(SMATCH_EXTRA, name, sym))
 187                 return;
 188         set_state(SMATCH_EXTRA, name, sym, state);
 189 }
 190 
 191 static void set_extra_nomod_helper(const char *name, struct symbol *sym, struct expression *expr, struct smatch_state *state)
 192 {
 193         call_extra_nomod_hooks(name, sym, expr, state);
 194         set_state(SMATCH_EXTRA, name, sym, state);
 195 }
 196 
 197 static char *get_pointed_at(const char *name, struct symbol *sym, struct symbol **new_sym)
 198 {
 199         struct expression *assigned;
 200 
 201         /*
 202          * Imagine we have an assignment: "foo = &addr;" then the other name
 203          * of "*foo" is addr.


2787                 }
2788                 state = get_state_expr(SMATCH_EXTRA, arg);
2789                 if (!estate_get_single_value(state, &dummy) && estate_has_hard_max(state)) {
2790                         sql_insert_caller_info(expr, HARD_MAX, i, "$",
2791                                                sval_to_str(estate_max(state)));
2792                 }
2793                 if (estate_has_fuzzy_max(state)) {
2794                         sql_insert_caller_info(expr, FUZZY_MAX, i, "$",
2795                                                sval_to_str(estate_get_fuzzy_max(state)));
2796                 }
2797                 i++;
2798         } END_FOR_EACH_PTR(arg);
2799 }
2800 
2801 static void set_param_value(const char *name, struct symbol *sym, char *key, char *value)
2802 {
2803         struct expression *expr;
2804         struct range_list *rl = NULL;
2805         struct smatch_state *state;
2806         struct symbol *type;

2807         char *key_orig = key;
2808         char *fullname;
2809         sval_t dummy;
2810 







2811         expr = symbol_expression(sym);
2812         fullname = get_variable_from_key(expr, key, NULL);
2813         if (!fullname)
2814                 return;
2815 
2816         type = get_member_type_from_key(expr, key_orig);
2817         str_to_rl(type, value, &rl);
2818         state = alloc_estate_rl(rl);
2819         if (estate_get_single_value(state, &dummy))
2820                 estate_set_hard_max(state);
2821         set_state(SMATCH_EXTRA, fullname, sym, state);
2822 }
2823 
2824 static void set_param_fuzzy_max(const char *name, struct symbol *sym, char *key, char *value)
2825 {
2826         struct expression *expr;
2827         struct range_list *rl = NULL;
2828         struct smatch_state *state;
2829         struct symbol *type;
2830         char *fullname;
2831         sval_t max;
2832 
2833         expr = symbol_expression(sym);
2834         fullname = get_variable_from_key(expr, key, NULL);
2835         if (!fullname)


2836                 return;
2837 
2838         state = get_state(SMATCH_EXTRA, fullname, sym);
2839         if (!state)
2840                 return;
2841         type = estate_type(state);
2842         str_to_rl(type, value, &rl);
2843         if (!rl_to_sval(rl, &max))
2844                 return;
2845         estate_set_fuzzy_max(state, max);
2846 }
2847 
2848 static void set_param_hard_max(const char *name, struct symbol *sym, char *key, char *value)
2849 {
2850         struct smatch_state *state;
2851         struct expression *expr;
2852         char *fullname;
2853 
2854         expr = symbol_expression(sym);
2855         fullname = get_variable_from_key(expr, key, NULL);
2856         if (!fullname)


2857                 return;
2858 
2859         state = get_state(SMATCH_EXTRA, fullname, sym);
2860         if (!state)
2861                 return;
2862         estate_set_hard_max(state);
2863 }
2864 
2865 struct sm_state *get_extra_sm_state(struct expression *expr)
2866 {
2867         char *name;
2868         struct symbol *sym;
2869         struct sm_state *ret = NULL;
2870 
2871         name = expr_to_known_chunk_sym(expr, &sym);
2872         if (!name)
2873                 goto free;
2874 
2875         ret = get_sm_state(SMATCH_EXTRA, name, sym);
2876 free: