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